“World data on a map” has many honest forms. A choropleth is only the
first. The package offers a full vocabulary; this vignette tours the
ones that need only maps – itself a suggested package, so
the map chunks are skipped when it is absent – and points to the rest,
which need sf or biscale as well.
Proportional-symbol (bubble) maps
For totals, a choropleth misleads: large values hide in small countries. Sized circles at centroids are the right idiom.
bubble_map(snap, population)
Spike maps
The same “totals” job as bubbles, with a different overplotting trade-off: spikes only grow upward, so dense regions (Europe, the Caribbean) stay legible.
spike_map(snap, population)
Both verbs place one symbol per country centroid, and the bundled centroid table does not cover every code in the codelist. On this snapshot five countries with population – Hong Kong, Macao, Gibraltar, the British Virgin Islands and Tuvalu – have no centroid and so no symbol. Each verb warns and names them, and counts them as missing rather than shown:
cov <- attr(suppressWarnings(bubble_map(snap, population)),
"countryatlas_provenance")$coverage
unlist(cov[c("n_total", "n_shown", "n_missing")])
#> n_total n_shown n_missing
#> 215 210 5
cov$missing_iso3c
#> [1] "GIB" "HKG" "MAC" "TUV" "VGB"Equal-area tile grids
Give every country the same visual weight so micro-states are
visible. The bundled grid covers 239 countries – see
?world_tiles for the ten it omits.
tile_map(snap, gdp_per_capita)
Flow maps
Great-circle arcs between country pairs from an origin–destination table.
od <- data.frame(
from = c("China", "Germany", "Brazil", "Nigeria"),
to = c("United States", "France", "Argentina", "India"),
weight = c(500, 200, 90, 60)
)
flow_map(od, from, to, weight)
Small multiples
facet_map() splits one choropleth into per-group panels
— the static counterpart to animate_world(), for print and
side-by-side comparison:
world_poly <- attach_geometry(snap, geometry = "polygon") |>
dplyr::filter(!is.na(continent))
facet_map(world_poly, gdp_per_capita, continent, style = "quantile", ncol = 3)
Labels
Centroid-anchored labels (names, ISO codes or flag emoji), with
ggrepel collision avoidance when available. Zoom with
coord_quickmap() rather than coord_cartesian()
– both replace the map’s coordinate system, but only the former keeps
the latitude-dependent aspect ratio that stops Europe coming out
stretched sideways.
mapdf <- attach_geometry(
dplyr::filter(snap, continent == "Europe"), geometry = "polygon"
)
world_map(mapdf, gdp_per_capita) +
geom_country_labels(repel = FALSE, size = 2.5) +
ggplot2::coord_quickmap(xlim = c(-25, 45), ylim = c(34, 72))
Maps that need optional packages
The remaining displays follow the same one-call pattern but require optional packages, so they are shown here as code:
# Bivariate choropleth (two variables at once) — needs `biscale` + `sf`
world_data(2020, c(gdp = "NY.GDP.PCAP.KD", life = "SP.DYN.LE00.IN"),
geometry = "sf") |>
bivariate_map(gdp, life)
# Area-honest cartogram — needs `cartogram` + `sf`
world_data(2020, c(pop = "SP.POP.TOTL"), geometry = "sf") |>
cartogram_map(pop, type = "dorling")
# The same Dorling cartogram as a first-class verb, with its tuning exposed
world_data(2020, c(pop = "SP.POP.TOTL"), geometry = "sf") |>
dorling_map(pop, k = 4)
# The fast flow-based cartogram (Gastner-Seguy-More) — needs `cartogramR`
world_data(2020, c(pop = "SP.POP.TOTL"), geometry = "sf") |>
cartogram_map(pop, type = "flow")
# Animated choropleth over a year panel — needs `gganimate`
world_data(2000:2020, c(gdp = "NY.GDP.PCAP.KD")) |>
animate_world(gdp)
# Interactive choropleth — needs `leaflet`, `ggiraph` or `plotly`
world_data(2020) |>
interactive_map(gdp_per_capita, engine = "plotly")Value-by-alpha: the cartogram’s non-distorting cousin
A cartogram equalises a denominator by deforming geometry.
value_by_alpha_map() does it by spending opacity instead,
so the world stays recognisable: colour carries the value, opacity
carries population, and a rate computed over a handful of people fades
toward the background rather than shouting.
mapdf <- attach_geometry(snap, geometry = "polygon")
value_by_alpha_map(mapdf, gdp_per_capita, population)
It needs no optional packages. The Honest maps vignette
covers when to reach for it rather than for
cartogram_map().
Country adjacency and distance
Two lightweight spatial helpers that aren’t choropleths at all.
distance_between() answers “how far apart” from the bundled
country_meta centroids — no sf or network
required:
distance_between("France", "Germany")
#> [1] 802.3524country_borders() / neighbors() answer “who
borders whom”, built from polygon topology, so they need
sf:
neighbors("France")
#> # A tibble: 8 × 3
#> iso3c neighbor neighbor_country
#> <chr> <chr> <chr>
#> 1 FRA SUR Suriname
#> 2 FRA LUX Luxembourg
#> 3 FRA ITA Italy
#> 4 FRA BRA Brazil
#> 5 FRA DEU Germany
#> 6 FRA CHE Switzerland
#> 7 FRA BEL Belgium
#> 8 FRA ESP SpainEach degrades gracefully: if the optional package is missing you get
a clear, actionable message (and animate_world() falls back
to a faceted small-multiple).
