Choosing an explodemap workflow

The short version

explodemap has four main user-facing workflows:

Goal Use
Explode a projected sf object that already has a grouping column explode_sf()
Join a lookup table before exploding explode_sf_with_lookup()
Download and explode U.S. county subdivisions by state explode_state()
Separate larger region blocks for national or multi-region layouts explode_grouped()
Add interactive selected-area zoom and information cards focus_map()

The best default is usually explode_sf(): prepare a projected sf object, add a region column, and let the package derive parameters from the data geometry.

Static exploded maps

Use explode_sf() when you already have polygon data and a grouping column:

result <- explode_sf(
  my_sf,
  region_col = "region",
  plot = FALSE,
  quiet = TRUE
)

Use explode_sf_with_lookup() when group membership lives in a separate table:

result <- explode_sf_with_lookup(
  my_sf,
  join_col = "GEOID",
  lookup = region_lookup,
  lookup_key = "geoid",
  region_col = "region",
  plot = FALSE,
  quiet = TRUE
)

Use explode_state() when you want the package to download U.S. Census TIGER/Line county subdivision data for a state:

result <- explode_state(
  state_fips = "34",
  crs = 32118,
  region_map = nj_regions,
  plot = FALSE,
  quiet = TRUE
)

Downloaded data is cached by tigris, so repeated runs are faster.

Dense municipal cores

The core two-level model is closed-form and deterministic. For very dense municipal cores, you may still see residual crowding after the analytical displacement. In that case, add the optional bounded refinement pass:

result <- explode_sf(
  my_sf,
  region_col = "region",
  refine = TRUE,
  refine_min_gap = 250,
  refine_max_shift = 150,
  plot = FALSE
)

Use refine = TRUE as a finishing pass, not as the first tuning knob. The most important parameter is refine_max_shift, which caps the extra correction per feature. Start small and increase only when dense cores still touch or visually crowd.

The default refine_within = "region" only refines pairs that share the same parent region. Use refine_within = "all" when the remaining crowding crosses region boundaries.

Grouped layouts

Use explode_grouped() when the map needs an additional layout level, such as a national map with multiple region blocks:

grouped <- explode_grouped(
  my_sf,
  region_col = "hhs_region",
  mode = "auto_collision",
  plot = FALSE,
  quiet = TRUE
)

The grouped workflow has three modes:

Mode Use when
"auto" Radial anchor placement is enough
"auto_collision" Region blocks need collision-aware anchor refinement
"manual" You want to provide anchor coordinates yourself

Interactive focus maps

Use focus_map() when the goal is exploration in Shiny or htmlwidgets, not a new static geometry layer. It lets users click or select a feature, zoom it into a readable viewport target, and show contextual fields in a non-blocking information card:

focus_map(
  result,
  group_col = "region",
  group_palette = c(North = "#4C78A8", Central = "#F58518", South = "#54A24B"),
  info_cols = c("NAME", "GEOID"),
  focus_size = 0.76,
  focus_padding = 40,
  lift_scale = 1.16,
  info_card_scale = 1.2
)

For Shiny:

ui <- fluidPage(
  focusmapOutput("map", height = "700px")
)

server <- function(input, output, session) {
  result <- explode_sf(munis, "region", plot = FALSE, quiet = TRUE)

  output$map <- renderFocusmap({
    focus_map(
      result,
      label_col = "NAME",
      id_col = "GEOID",
      group_col = "region",
      group_palette = c(North = "#4C78A8", Central = "#F58518", South = "#54A24B"),
      info_cols = c("GEOID", "population")
    )
  })
}

The Shiny widget publishes selections at input$map_selected. Use that reactive value to drive side panels, tables, or linked charts.

For region or category filters, explode_section() can explode only the selected section while keeping the rest of the layer as geographic context:

focused <- explode_section(
  munis,
  section_col = "nj_region",
  section = input$region,
  region_col = "county_name",
  alpha_r = 900,
  alpha_l = 600,
  plot = FALSE,
  quiet = TRUE
)

focus_map(
  focused,
  label_col = "NAME",
  id_col = "GEOID",
  context_col = ".explodemap_role",
  context_mode = "fade",
  context_opacity = 0.16,
  performance_mode = TRUE
)

This keeps focused sections compact while preserving the full map outline as context. Use context_mode = "hide" when the background should be available to the layout but not visible in the widget.

Performance guidance

Before exploding or focusing:

Installed examples

Small local examples:

source(system.file("examples/basic_explode_sf.R", package = "explodemap"))
source(system.file("examples/collision_refinement.R", package = "explodemap"))
source(system.file("examples/lookup_workflow.R", package = "explodemap"))
source(system.file("examples/manual_parameter_tuning.R", package = "explodemap"))

Interactive examples that download public data:

if (interactive()) {
  shiny::runApp(system.file("examples/focusmap_munis_app.R", package = "explodemap"))
  shiny::runApp(system.file("examples/focusmap_counties_app.R", package = "explodemap"))
}