My question relates to plotting a whole U.S. map on MSA level via choroplethr and choroplethrZip.
In the example below, we plot 1) Census population information on a U.S. map on county level and 2) a zoomed map of a selected Metropolitan/Micropolitan Statistical Area (MSA) level.
Example R code:
library(choroplethr)
library(choroplethrZip)
?zip.regions
data(zip.regions)
head(zip.regions)
?df_pop_county
data(df_pop_county)
df_pop_county
?df_pop_zip
data(df_pop_zip)
# U.S. County Population Data
county_choropleth(df_pop_county, legend = "Population")
# NY-NJ-PA MSA Population Data
zip_choropleth(df_pop_zip,
msa_zoom = "New York-Newark-Jersey City, NY-NJ-PA",
title = "2012 NY-Newark-Jersey City MSA\nZCTA Population Estimates",
legend = "Population")
Instead of only a zoom into a specific MSA, can we also plot a whole MSA-level U.S. map? An approach like
zip_choropleth(df_pop_zip, legend = "Population")
did not work, and would also likely plot the ZCTA regions, not MSA regions.
Thank you!
You can use the state_zoom
argument to zip_choropleth
. But as noted in the package documents there is no MSA-based choropleth. An example of how this looks:
states <- unique( zip.regions$state.name)
lower48 <- states[ ! states %in% c('alaska','hawaii') ]
zip_choropleth(df_pop_zip,
state_zoom = lower48 ,
title = "2012 MSA\nZCTA Population Estimates",
legend = "Population")
It looks mostly grey because the ZCTA borders are rendered in grey and they are dense at this scale. If you run the code and look at a higher resolution you can see more of the fill.
An alternative I'd recommend for your task is the tidycensus
package. See the code snippet below which I believe creates a map similar to what you're interested in. I select only a few states to clarify the visual, and plot at the county level. I also only plot the top 85 percent of MSAs by total population. This eliminates Danville Virginia for example.
# adapted from https://walkerke.github.io/2017/06/comparing-metros/
library(viridis)
library(ggplot2)
library(tidycensus)
library(tidyverse)
library(tigris)
library(sf)
options(tigris_class = "sf")
options(tigris_use_cache = TRUE)
# census_api_key("YOUR KEY HERE")
acs_var <- 'B01003_001E'
tot <- get_acs(geography = "county", variables = acs_var, state=c("PA", "VA", "DC","MD"),
geometry = TRUE)
head(tot)
metros <- core_based_statistical_areas(cb = TRUE) %>%
select(metro_name = NAME)
wc_tot <- st_join(tot, metros, join = st_within,
left = FALSE)
pct85 <- wc_tot %>% group_by(metro_name) %>%
summarise(tot_pop=sum(estimate)) %>% summarise(pct85 = quantile(tot_pop, c(0.85)))
pct85_msas = wc_tot %>% group_by(metro_name) %>%
summarise(tot_pop=sum(estimate)) %>% filter(tot_pop > pct85$pct85[1])
head(wc_tot)
ggplot(filter(wc_tot, metro_name %in% pct85_msas$metro_name),
aes(fill = estimate, color = estimate)) +
geom_sf() +
coord_sf(crs=3857) +
#facet_wrap(~metro_name, scales = "free", nrow = 1) +
theme_minimal() +
theme(aspect.ratio = 1) +
scale_fill_viridis() +
scale_color_viridis()
Resulting plot:
The facet line that I've commented out seems to be an area of active devlopment in ggplot. I was getting an error with it, but the source article I mentioned shows how it can be put to good use to display one panel per MSA, which makes a lot of sense. See https://github.com/tidyverse/ggplot2/issues/2651.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With