基于ggplot2绘制分性别且跨两个时间段的人口金字塔
双时间段性别对比人口金字塔实现方案
嘿,作为刚接触R和ggplot2的新手,能想到把性别和双时间段结合做人口金字塔真的很赞!完全可以实现,我用模拟数据给你一步步拆解,你替换成自己的真实数据就能用啦~
第一步:准备数据(模拟+处理)
首先我们需要构造符合要求的数据集,核心是包含年龄段、性别、时间段、人口数这几个字段。我先模拟一份数据,你可以直接替换成自己的真实数据:
library(tidyverse) # 加载tidyverse包,包含ggplot2和数据处理工具 # 模拟数据,保证结果可重复 set.seed(123) age_groups <- c("0-9", "10-19", "20-29", "30-39", "40-49", "50-59", "60+") df <- expand.grid( age = age_groups, gender = c("男", "女"), period = c("2010", "2020") ) %>% mutate(population = sample(1000:5000, nrow(.), replace = TRUE)) %>% # 关键操作:把男性人口转为负数,这样能在x轴左侧绘制男性条形 mutate(population = ifelse(gender == "男", -population, population))
第二步:用ggplot2绘制双时间段金字塔
这里我们用facet_wrap把两个时间段的金字塔并排展示,既清晰又方便对比:
ggplot(df, aes(x = population, y = age, fill = gender)) + # 绘制条形图,position="identity"避免条形重叠 geom_col(position = "identity") + # 按时间段分面板,并排展示 facet_wrap(~period) + # 调整x轴:把负数刻度转为正数显示,更符合阅读习惯 scale_x_continuous( breaks = seq(-5000, 5000, 1000), labels = abs(seq(-5000, 5000, 1000)), expand = c(0, 0) # 去掉轴边距,让条形贴紧边缘 ) + # 自定义男女的填充颜色,你可以换成自己喜欢的颜色 scale_fill_manual(values = c("男" = "#1f77b4", "女" = "#ff7f0e")) + # 添加标题和轴标签 labs( title = "2010 vs 2020年人口金字塔对比", x = "人口数量", y = "年龄段", fill = "性别" ) + # 添加垂直中线,区分男女两边 geom_vline(xintercept = 0, color = "black", linewidth = 0.8) + # 用简洁的主题,再微调样式 theme_minimal() + theme( plot.title = element_text(hjust = 0.5, size = 14, face = "bold"), axis.title = element_text(size = 12), strip.text = element_text(size = 12, face = "bold") # 时间段标签加粗 )
小Tips给新手
- 如果你的年龄段是数值(比如0,10,20...),记得转成因子并指定顺序,不然ggplot会按数值排序,导致年龄段顺序混乱:
df$age <- factor(df$age, levels = c("0-9", "10-19", ...)) - 如果想把两个时间段的金字塔放在同一个面板里(用颜色区分时间段),可以调整
aes里的分组和填充,不过这种方式不如分面板直观,新手优先推荐分面板的版本~
内容的提问来源于stack exchange,提问作者PVS
相关产品推荐
相关产品推荐

