explode_grouped() extends the core two-level
exploded-map workflow with a three-level hierarchy for multi-region or
national-scale layouts.
This grouped extension is most useful when a standard two-level explosion still leaves region blocks visually crowded or difficult to compare across a larger spatial extent.
The three levels are:
Level 1 — Local explosion. Units within each parent region are displaced using the centroid-driven field from the core algorithm. The geometric guarantees of Propositions 1–3 apply at this level.
Level 2 — Radial anchor placement. Parent region centroids are displaced radially outward from the national centroid to generate initial anchor positions for each region block.
Level 3 — Collision-aware refinement (optional). Overlapping anchors are iteratively repelled while a spring term maintains proximity to the original radial targets.
Levels 2 and 3 preserve structural grouping and directional correspondence rather than topological coverage. The formal geometric guarantees of Propositions 1–3 apply strictly at Level 1.
We create a small dataset with six units in three regions, spread
across a wider spatial extent than the two-region example in
vignette("getting-started").
sq <- function(xmin, ymin, size = 1000) {
st_polygon(list(matrix(
c(xmin, ymin,
xmin + size, ymin,
xmin + size, ymin + size,
xmin, ymin + size,
xmin, ymin),
ncol = 2,
byrow = TRUE
)))
}
geom <- st_sfc(
sq(0, 0), sq(3000, 0), # R1
sq(9000, 0), sq(12000, 0), # R2
sq(24000, 0), sq(27000, 0), # R3
crs = 3857
)
x <- st_sf(
id = paste0("u", 1:6),
region = c("R1", "R1", "R2", "R2", "R3", "R3"),
geometry = geom
)explode_grouped() supports three anchor placement
modes:
| Mode | Description |
|---|---|
"auto" |
Level 2 only — radial placement without collision resolution |
"auto_collision" |
Level 2 + Level 3 — radial placement with iterative refinement |
"manual" |
User-supplied anchor coordinates |
The simplest call uses mode = "auto":
g_auto <- explode_grouped(
x,
region_col = "region",
mode = "auto",
plot = FALSE,
quiet = TRUE
)
class(g_auto)
#> [1] "grouped_exploded_map" "exploded_map" "list"
print(g_auto)
#>
#> -- Grouped Layout (grouped) ------------------------------
#> n units : 6
#> n regions : 3
#> mode : auto
#> alpha_l : 2.4 km
#> p : 1.25
#> kappa : 1.8
#> padding : 50 kmThe result is a grouped_exploded_map S3 object, which
also inherits from exploded_map:
names(g_auto)
#> [1] "sf_orig" "sf_local" "sf_grouped" "sf_grouped_wgs"
#> [5] "stats" "params" "anchors" "plots"
#> [9] "diagnostics"Plot the grouped layout:
mode = "auto_collision" adds Level 3 refinement.
Overlapping region blocks are iteratively repelled while a spring term
pulls them back toward their radial targets:
g_collide <- explode_grouped(
x,
region_col = "region",
mode = "auto_collision",
plot = FALSE,
quiet = TRUE
)
plot(g_collide)The anchor table reports the resulting block radii and coordinates:
plot(g, "all") shows the original, locally exploded, and
grouped layouts side by side:
layout_regions() computes anchor positions as a
standalone step, which is useful for custom workflows or manual
adjustment:
anchors <- layout_regions(
x,
region_col = "region",
mode = "auto",
quiet = TRUE
)
anchors[, c("region", "block_radius", "n_units", "anchor_x", "anchor_y")]
#> # A tibble: 3 × 5
#> region block_radius n_units anchor_x anchor_y
#> <chr> <dbl> <int> <dbl> <dbl>
#> 1 R1 1500 2 -73279. 500
#> 2 R2 1500 2 -57079. 500
#> 3 R3 1500 2 102879. 500You can edit anchor positions and pass them back into
explode_grouped():
manual_anchors <- anchors
manual_anchors$anchor_x <- manual_anchors$anchor_x + c(0, 500, 1000)
manual_anchors$anchor_y <- manual_anchors$anchor_y + c(0, 250, 500)
g_manual <- explode_grouped(
x,
region_col = "region",
mode = "manual",
anchors = manual_anchors,
plot = FALSE,
quiet = TRUE
)
plot(g_manual)Level 1 parameters control local displacement within regions:
| Parameter | Default | Purpose |
|---|---|---|
alpha_l |
derived | Local expansion magnitude (metres) |
p |
1.25 | Distance-scaling exponent |
gamma_l |
1.136 | Local clearance coefficient (used if alpha_l is
NULL) |
Level 2 and Level 3 parameters control anchor placement and refinement:
| Parameter | Default | Purpose |
|---|---|---|
kappa |
1.8 | Radial expansion factor |
padding |
50000 | Base padding (map units) |
delta |
15000 | Log-density scaling factor |
lambda |
0.18 | Spring coefficient for refinement |
eta |
0.18 | Repulsion step size for refinement |
padding_sep |
20000 | Minimum separation between blocks |
For real-world data, these defaults are tuned for national-scale U.S.
layouts such as states grouped into larger reporting regions. For
smaller or larger extents, adjust padding,
delta, and padding_sep to match your
coordinate system and visual scale.
summary(g_collide)
#>
#> Grouped Exploded Map Summary
#> ============================
#> Dataset: Grouped Layout
#> Units: 6
#> Regions: 3
#> Grouped by: region
#> Anchor mode: auto_collision
#>
#> Level 1 Parameters
#> alpha_l: 2.4 km (local expansion)
#> p: 1.25
#>
#> Anchor Parameters
#> kappa: 1.8
#> padding: 50 km
#> delta: 15 km
#> lambda: 0.18
#> eta: 0.18
#>
#> Anchor Radii
#> # A tibble: 3 × 3
#> region block_radius n_units
#> <chr> <dbl> <int>
#> 1 R1 3910. 2
#> 2 R2 3910. 2
#> 3 R3 3910. 2Grouped results can be passed directly to focus_map().
The widget automatically uses sf_grouped_wgs, so the
displayed geometry matches the grouped layout:
focus_map(
g_collide,
label_col = "id",
id_col = "id",
group_col = "region",
info_cols = c("region"),
performance_mode = TRUE
)Inside Shiny, pair
explode_grouped(..., quiet = TRUE, plot = FALSE) with
renderFocusmap() to avoid console noise and accidental plot
printing.
| Field | Contents |
|---|---|
sf_orig |
Original input geometries |
sf_local |
Geometries after Level 1 local explosion |
sf_grouped |
Final geometries after anchor displacement |
sf_grouped_wgs |
Final geometries in WGS84 (EPSG:4326) |
stats |
Geometry statistics from compute_stats() |
params |
All parameters used |
anchors |
Anchor table with block radii and positions |
plots |
ggplot objects for original, local, and grouped layouts |
diagnostics |
Label, region column, centroid mode, and anchor mode |
The local explosion stage (Level 1) preserves the package’s core geometric guarantees: exact feature-level geometry preservation (Proposition 1), radial ordering within regions (Proposition 2), and bounded displacement (Proposition 3).
The grouped anchor stage (Levels 2–3) is a higher-level layout extension. It preserves grouping structure and directional correspondence rather than topological coverage.
For the core two-level workflow and parameter derivation, see
vignette("getting-started").
For full paper-scale examples including cross-state calibration,
Canada, and HHS grouped layouts, see
vignette("reproducing-paper-examples").