canada <- rnaturalearth::ne_states(country = "canada", returnclass = "sf") |>
st_make_valid()
It has been a while since I posted something! But today I wanted to quickly experiment and create a map where I could separate/explode the spatial geometries. Let’s first download the polygon data for Canada.
As we can see, there are three different regions.
canada |>
distinct(region)
#> region
#> 1 Western Canada
#> 2 Eastern Canada
#> 3 Northern Canada
These regions can be visualized using ggplot2
and sf
.
# Get a good CRS for Canada
crsuggest::suggest_crs(canada)
#> # A tibble: 10 × 6
#> crs_code crs_name crs_type crs_gcs crs_units crs_proj4
#> <chr> <chr> <chr> <dbl> <chr> <chr>
#> 1 5931 WGS 84 / EPSG Arctic Regional … project… 4326 m +proj=lc…
#> 2 3979 NAD83(CSRS) / Canada Atlas Lam… project… 4617 m +proj=lc…
#> 3 3978 NAD83 / Canada Atlas Lambert project… 4269 m +proj=lc…
#> 4 3348 NAD83(CSRS) / Statistics Canad… project… 4617 m +proj=lc…
#> 5 3347 NAD83 / Statistics Canada Lamb… project… 4269 m +proj=lc…
#> 6 5926 WGS 84 / EPSG Arctic Regional … project… 4326 m +proj=lc…
#> 7 5921 WGS 84 / EPSG Arctic Regional … project… 4326 m +proj=lc…
#> 8 6350 NAD83(2011) / Conus Albers project… 6318 m +proj=ae…
#> 9 5072 NAD83(NSRS2007) / Conus Albers project… 4759 m +proj=ae…
#> 10 5071 NAD83(HARN) / Conus Albers project… 4152 m +proj=ae…
canada <- canada |>
st_transform(5931)
canada |>
ggplot(aes(fill = region)) +
geom_sf()
With this following code, we can find the centroid of each region and shift the centers of the new polygons.
canada_exploded <- canada |>
group_by(region) |>
mutate(region_centroid = st_centroid(st_union(geometry))) |>
ungroup() |>
mutate(geometry = (geometry - region_centroid) * 0.9 + region_centroid)
st_crs(canada_exploded)
#> Coordinate Reference System: NA
As seen above, for a reason I do not know, we have lost the CRS after the operation, so I have to set it back before visualizing it.
canada_exploded <- canada_exploded |>
st_set_crs(5931)
canada_exploded |>
ggplot(aes(fill = region)) +
geom_sf()
Session info
#> ─ Session info ───────────────────────────────────────────────────────────────────────────────────────────────────────
#> setting value
#> version R version 4.5.0 (2025-04-11)
#> os Linux Mint 22
#> system x86_64, linux-gnu
#> ui X11
#> language en_CA:en
#> collate en_CA.UTF-8
#> ctype en_CA.UTF-8
#> tz America/Montreal
#> date 2025-06-12
#> pandoc 3.1.3 @ /usr/bin/ (via rmarkdown)
#> quarto 1.6.39 @ /usr/local/bin/quarto
#>
#> ─ Packages ───────────────────────────────────────────────────────────────────────────────────────────────────────────
#> ! package * version date (UTC) lib source
#> P base64enc 0.1-3 2015-07-28 [?] RSPM (R 4.5.0)
#> P cachem 1.1.0 2024-05-16 [?] RSPM (R 4.5.0)
#> P class 7.3-23 2025-01-01 [?] CRAN (R 4.4.2)
#> P classInt 0.4-11 2025-01-08 [?] RSPM
#> P cli 3.6.5 2025-04-23 [?] CRAN (R 4.5.0)
#> P codetools 0.2-20 2024-03-31 [?] CRAN (R 4.4.0)
#> P crosstalk 1.2.1 2023-11-23 [?] RSPM
#> P crsuggest 0.4 2022-07-06 [?] RSPM
#> P DBI 1.2.3 2024-06-02 [?] RSPM (R 4.5.0)
#> P devtools 2.4.5 2022-10-11 [?] RSPM (R 4.5.0)
#> P digest 0.6.37 2024-08-19 [?] RSPM (R 4.5.0)
#> P dplyr * 1.1.4 2023-11-17 [?] RSPM (R 4.5.0)
#> P e1071 1.7-16 2024-09-16 [?] RSPM (R 4.5.0)
#> P ellipsis 0.3.2 2021-04-29 [?] RSPM (R 4.5.0)
#> P evaluate 1.0.3 2025-01-10 [?] RSPM
#> P extrafont 0.19 2023-01-18 [?] RSPM
#> P extrafontdb 1.0 2012-06-11 [?] RSPM
#> P farver 2.1.2 2024-05-13 [?] RSPM (R 4.5.0)
#> P fastmap 1.2.0 2024-05-15 [?] RSPM (R 4.5.0)
#> P forcats * 1.0.0 2023-01-29 [?] RSPM
#> P fs 1.6.6 2025-04-12 [?] RSPM
#> P generics 0.1.4 2025-05-09 [?] RSPM
#> P ggplot2 * 3.5.2 2025-04-09 [?] RSPM
#> P ggpmthemes * 0.0.2 2025-04-14 [?] Github (pmassicotte/ggpmthemes@993d61e)
#> P glue 1.8.0 2024-09-30 [?] RSPM (R 4.5.0)
#> P gtable 0.3.6 2024-10-25 [?] RSPM
#> P hms 1.1.3 2023-03-21 [?] RSPM
#> P htmltools 0.5.8.1 2024-04-04 [?] RSPM (R 4.5.0)
#> P htmlwidgets 1.6.4 2023-12-06 [?] RSPM
#> P httpuv 1.6.16 2025-04-16 [?] RSPM
#> P httr 1.4.7 2023-08-15 [?] RSPM
#> P jsonlite 2.0.0 2025-03-27 [?] RSPM (R 4.5.0)
#> P KernSmooth 2.23-26 2025-01-01 [?] CRAN (R 4.4.2)
#> P knitr 1.50 2025-03-16 [?] RSPM
#> P later 1.4.2 2025-04-08 [?] RSPM
#> P lattice 0.22-5 2023-10-24 [?] CRAN (R 4.3.3)
#> P leafem 0.2.4 2025-05-01 [?] RSPM
#> P leaflet 2.2.2 2024-03-26 [?] RSPM
#> P lifecycle 1.0.4 2023-11-07 [?] RSPM (R 4.5.0)
#> P lubridate * 1.9.4 2024-12-08 [?] RSPM
#> P magrittr 2.0.3 2022-03-30 [?] RSPM (R 4.5.0)
#> P mapview 2.11.2 2023-10-13 [?] RSPM
#> P memoise 2.0.1 2021-11-26 [?] RSPM (R 4.5.0)
#> P mime 0.13 2025-03-17 [?] RSPM
#> P miniUI 0.1.2 2025-04-17 [?] RSPM (R 4.5.0)
#> P pillar 1.10.2 2025-04-05 [?] RSPM
#> P pkgbuild 1.4.8 2025-05-26 [?] RSPM (R 4.5.0)
#> P pkgconfig 2.0.3 2019-09-22 [?] RSPM (R 4.5.0)
#> P pkgload 1.4.0 2024-06-28 [?] RSPM
#> P png 0.1-8 2022-11-29 [?] RSPM
#> P processx 3.8.6 2025-02-21 [?] RSPM
#> P profvis 0.4.0 2024-09-20 [?] RSPM (R 4.5.0)
#> P promises 1.3.3 2025-05-29 [?] RSPM (R 4.5.0)
#> P proxy 0.4-27 2022-06-09 [?] RSPM (R 4.5.0)
#> P ps 1.9.1 2025-04-12 [?] RSPM
#> P purrr * 1.0.4 2025-02-05 [?] RSPM
#> P quarto * 1.4.4 2024-07-20 [?] RSPM
#> P R6 2.6.1 2025-02-15 [?] RSPM (R 4.5.0)
#> P raster 3.6-32 2025-03-28 [?] RSPM
#> P RColorBrewer 1.1-3 2022-04-03 [?] RSPM (R 4.5.0)
#> P Rcpp 1.0.14 2025-01-12 [?] CRAN (R 4.5.0)
#> P readr * 2.1.5 2024-01-10 [?] RSPM
#> P remotes 2.5.0 2024-03-17 [?] RSPM
#> P renv 1.1.4 2025-03-20 [?] RSPM
#> P rlang 1.1.6 2025-04-11 [?] RSPM
#> P rmarkdown 2.29 2024-11-04 [?] RSPM
#> P rnaturalearth 1.0.1 2023-12-15 [?] RSPM
#> P rnaturalearthhires * 1.0.0.9000 2025-04-15 [?] Github (ropensci/rnaturalearthhires@153b0ea)
#> P rstudioapi 0.17.1 2024-10-22 [?] RSPM
#> P Rttf2pt1 1.3.12 2023-01-22 [?] RSPM (R 4.5.0)
#> P s2 1.1.9 2025-05-23 [?] RSPM
#> P satellite 1.0.5 2024-02-10 [?] RSPM
#> P scales 1.4.0 2025-04-24 [?] RSPM
#> P sessioninfo 1.2.3 2025-02-05 [?] RSPM (R 4.5.0)
#> P sf * 1.0-21 2025-05-15 [?] RSPM
#> P shiny 1.10.0 2024-12-14 [?] RSPM (R 4.5.0)
#> P sp 2.2-0 2025-02-01 [?] RSPM
#> P stringi 1.8.7 2025-03-27 [?] RSPM
#> P stringr * 1.5.1 2023-11-14 [?] RSPM (R 4.5.0)
#> P terra 1.8-54 2025-06-01 [?] RSPM
#> P tibble * 3.3.0 2025-06-08 [?] RSPM (R 4.5.0)
#> P tidyr * 1.3.1 2024-01-24 [?] RSPM (R 4.5.0)
#> P tidyselect 1.2.1 2024-03-11 [?] RSPM (R 4.5.0)
#> P tidyverse * 2.0.0 2023-02-22 [?] RSPM
#> P timechange 0.3.0 2024-01-18 [?] RSPM
#> P tzdb 0.5.0 2025-03-15 [?] RSPM
#> P units 0.8-7 2025-03-11 [?] RSPM
#> P urlchecker 1.0.1 2021-11-30 [?] RSPM (R 4.5.0)
#> P usethis 3.1.0 2024-11-26 [?] RSPM (R 4.5.0)
#> P utf8 1.2.6 2025-06-08 [?] RSPM (R 4.5.0)
#> P vctrs 0.6.5 2023-12-01 [?] RSPM (R 4.5.0)
#> P withr 3.0.2 2024-10-28 [?] RSPM
#> P wk 0.9.4 2024-10-11 [?] RSPM
#> P xfun 0.52 2025-04-02 [?] RSPM
#> P xtable 1.8-4 2019-04-21 [?] RSPM (R 4.5.0)
#> P yaml 2.3.10 2024-07-26 [?] RSPM
#>
#> [1] /tmp/RtmpZPTuyN/renv-use-libpath-279bb9681aab5f
#> [2] /home/filoche/.cache/R/renv/sandbox/linux-linuxmint-noble/R-4.5/x86_64-pc-linux-gnu/9a444a72
#>
#> * ── Packages attached to the search path.
#> P ── Loaded and on-disk path mismatch.
#>
#> ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Citation
BibTeX citation:
@online{massicotte2023,
author = {Massicotte, Philippe},
title = {Separating/Exploding Spatial Features with {R}},
date = {2023-08-15},
url = {https://www.pmassicotte.com/posts/2023-08-15-map-explode/},
langid = {en}
}
For attribution, please cite this work as:
Massicotte, Philippe. 2023. “Separating/Exploding Spatial Features
with R.” August 15, 2023. https://www.pmassicotte.com/posts/2023-08-15-map-explode/.