Last active
June 27, 2025 23:05
-
-
Save walkerke/8b4230d3e1a098ed9f79ee9c62ac5e74 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
library(tidyverse) | |
library(tidycensus) | |
# Get the data | |
pyramid_data <- get_estimates( | |
geography = "state", | |
product = "characteristics", | |
breakdown = c("AGEGROUP", "SEX"), | |
breakdown_labels = TRUE, | |
vintage = 2024, | |
year = 2024 | |
) %>% | |
filter(AGEGROUP != "All ages", SEX != "Both sexes", NAME %in% c("Maine", "Utah")) %>% | |
group_by(NAME) %>% | |
mutate( | |
value_pct = value / sum(value) * 100, | |
value_pct = ifelse(SEX == "Male", -value_pct, value_pct) | |
) %>% | |
ungroup() | |
# Create enhanced population pyramids | |
ggplot(pyramid_data, aes(x = value_pct, y = AGEGROUP, fill = SEX)) + | |
geom_col(alpha = 0.9, width = 0.85) + | |
geom_vline(xintercept = 0, color = "gray40", linewidth = 0.5) + | |
scale_x_continuous( | |
labels = function(x) paste0(abs(x), "%"), | |
expand = expansion(mult = c(0.05, 0.05)) | |
) + | |
scale_y_discrete( | |
labels = function(x) str_remove_all(x, "Age\\s|\\syears") | |
) + | |
scale_fill_manual( | |
values = c("Female" = "#A23B72", "Male" = "#2E86AB"), | |
breaks = c("Male", "Female") # This controls the legend order | |
) + | |
facet_wrap(~NAME, scales = "free_x") + | |
labs( | |
title = "The Oldest (Maine) and Youngest (Utah) States in the U.S.", | |
subtitle = "Population distribution by age and sex, 2024", | |
x = "Percentage of State Population", | |
y = "Age Group", | |
caption = "Source: U.S. Census Bureau, Vintage 2024 Population Estimates | tidycensus R package" | |
) + | |
theme_minimal(base_size = 11) + | |
theme( | |
# Title and text styling | |
plot.title = element_text(face = "bold", size = 18, hjust = 0.5, | |
margin = margin(b = 5)), | |
plot.subtitle = element_text(color = "gray50", size = 13, hjust = 0.5, | |
margin = margin(b = 15)), | |
plot.caption = element_text(color = "gray60", size = 9, hjust = 1, | |
margin = margin(t = 15)), | |
# Facet styling | |
strip.text = element_text(size = 14, face = "bold", color = "gray20"), | |
strip.background = element_rect(fill = "gray95", color = NA), | |
# Axis styling | |
axis.title.x = element_text(size = 11, margin = margin(t = 10)), | |
axis.title.y = element_text(size = 11, margin = margin(r = 10)), | |
axis.text.y = element_text(size = 10, color = "gray30"), | |
axis.text.x = element_text(size = 10, color = "gray30"), | |
# Grid styling | |
panel.grid.major.y = element_line(color = "gray90", linewidth = 0.3), | |
panel.grid.minor.y = element_blank(), | |
panel.grid.major.x = element_line(color = "gray85", linewidth = 0.3), | |
panel.grid.minor.x = element_blank(), | |
# Panel styling | |
panel.spacing = unit(1.5, "lines"), | |
# Legend styling - moved to bottom with horizontal layout | |
legend.position = "bottom", | |
legend.direction = "horizontal", | |
legend.title = element_text(size = 10, margin = margin(r = 3)), # Reduced spacing | |
legend.text = element_text(size = 10), | |
legend.key.width = unit(1.5, "cm"), | |
legend.key.height = unit(0.3, "cm"), | |
legend.margin = margin(t = 5, b = 0), | |
legend.spacing.x = unit(0.3, "cm"), | |
# Overall plot margins | |
plot.margin = margin(20, 20, 10, 20) | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment