Choropleth Maps in R (2025 Edition)
Choropleth maps remain a powerful way to convey metrics across geographic regions in seconds. Whether you're comparing state-level growth rates or population densities, a shaded map conveys meaning faster—and more memorably—than tables or bar charts.
Why Choropleths Work
They excel at showing variation across regions while being visually intuitive. Tracking demographics or performance metrics across states or districts becomes immediately clearer—perfect when you have just 15–20 seconds to make an impression.
Modern Workflow for Choropleth Mapping in R
Here’s how to build refined, maintainable choropleth maps using robust tools:
Get geographic data
Use modern spatial packages like sf to read shapefiles or geo-formats (.shp, GeoJSON, etc.).
Prepare your data
Load or generate metric data (e.g., population density, growth rate).
Join geographic and metric data
Use dplyr::left_join() to merge your dataset with spatial data.
Map with ggplot2 and viridis
Create clear, accessible maps with geom_sf() and color scales.
Add labels and context
Use geom_sf_text() or geom_sf_label() to annotate maps.
Visualize multiple variables
Compare metrics side by side using facets, patchwork, or cowplot.
What’s Changed for 2025
- sf + ggplot2 as the standard for spatial workflows.
- viridis palettes for accessibility and clarity.
- Improved annotation with modern labeling tools.
- Faceted and combined layouts for richer comparisons.
- Efficient joins and tidy workflows that scale well to large or complex geographies.
Why These Updates Matter
- Cleaner code: Easier to read, maintain, and scale.
- Accessible visuals: Inclusive and clearer across screens and print.
- Flexibility: Supports interactive dashboards and evolving boundaries.
- Future-ready: Aligns with modern data science and visualization practices.
Sample R Workflow (2025 Style)
library(sf); library(dplyr); library(ggplot2); library(viridis); library(patchwork)
Load US state shapefile
us_states <- st_read("us_states.shp")
Example data
df <- data.frame(id = us_states$STATE_ID,
pop_density = runif(nrow(us_states), 10, 500),
growth_rate = runif(nrow(us_states), -0.02, 0.05))
Merge
us_map <- us_states %>% left_join(df, by = c("STATE_ID" = "id"))
Plot population density
p1 <- ggplot(us_map) +
geom_sf(aes(fill = pop_density), color = "white") +
scale_fill_viridis_c(option = "magma", name = "Density") +
theme_minimal() + labs(title = "Population Density")
Plot growth rate
p2 <- ggplot(us_map) +
geom_sf(aes(fill = growth_rate), color = "white") +
scale_fill_viridis_c(option = "plasma", name = "Growth Rate") +
theme_minimal() + labs(title = "Population Growth Rate")
Combine
p1 + p2
Summary
Choropleth maps in R have evolved significantly with the sf–ggplot2–tidyverse ecosystem at the center. Modern workflows emphasize cleaner code, scalable joins, accessible color schemes, and flexible layouts. By adopting these practices, analysts and data scientists can build clearer, more inclusive, and future-proof maps that effectively communicate geographic insights across diverse audiences.
This article was originally published on Perceptive Analytics.
In San Antonio, our mission is simple — to enable businesses to unlock value in data. For over 20 years, we’ve partnered with more than 100 clients — from Fortune 500 companies to mid-sized firms — helping them solve complex data analytics challenges. As a leading Power BI Consultant in San Antonio and Tableau Consultant in San Antonio, we turn raw data into strategic insights that drive better decisions.
Top comments (0)