如何用ggplot创建分组堆叠柱状图(非分面形式)
问题描述
需要用ggplot绘制堆叠柱状图,具体需求:
- X轴显示月份编号
- Y轴为各物种每月的总数量
- 同一月份下,有多少年份的采样数据就并列展示多少根堆叠柱(不同年份的柱子对应同一月份)
现有代码通过分面展示年份,不符合预期效果。
示例数据集
Sp <- data.frame(Species = c("A","A","A","A","A","A","A","A","A","A","A","B","B","B","B","B","C","C","C","C","C","C","C","C","C","C","C","C","C","C","C","C","C","C","C","C","C","C"), Month= c("2","3","4","4","4","7","3","4","4","5","6","4","5","6","6","7","4","3","4","5","6","7","3","4","4","5","6","4","5","6","4","5","6","2","2","8","5","5"), Year= c("2018","2005","2006","2006","2006","2006","2008","2008","2008","2008","2018","2009","2009","2009","2018","2009","2009","2009","2009","2009","2018","2005","2005","2005","2006","2006","2005","2006","2005","2005","2005","2009","2009","2009","2018","2018","2018","2018"))
现有代码
Sp%>% group_by(Month, Year, Species)%>% ggplot(aes(Month)) + geom_bar(aes(fill= Species),stat='count')+ facet_wrap( ~ Year, nrow = 1)
输出差异
- 当前输出:按年份分面,每个年份单独展示该年份的月份堆叠柱
- 预期效果:X轴为月份,同一月份下并列展示对应年份的堆叠柱,柱子内部按物种堆叠,体现各物种当月总数量
解决方法
1. 数据预处理
先按月份、年份、物种分组统计数量,同时将月份转为有序因子,保证X轴按数字顺序排列:
library(dplyr) library(ggplot2) # 统计各分组的个体数量,并整理月份顺序 Sp_sum <- Sp %>% group_by(Month, Year, Species) %>% summarise(Count = n(), .groups = "drop") %>% mutate(Month = factor(Month, levels = sort(unique(Month))))
2. 绘制目标堆叠柱状图
将Year作为并列分组的依据,使用position_dodge实现同一月份下不同年份柱子的并列展示:
ggplot(Sp_sum, aes(x = Month, y = Count, fill = Species, group = Year)) + geom_col(position = position_dodge(preserve = "single")) + labs(x = "月份", y = "物种总数量", fill = "物种") + theme_bw()
关键说明
geom_col:直接使用预处理好的Count值,比geom_bar(stat='count')更清晰可控position_dodge(preserve = "single"):确保同一月份下的不同年份柱子并列,且即使某月份只有一个年份数据,柱子宽度也与其他月份一致,避免视觉上的宽窄不一- 有序因子
Month:避免X轴按字母顺序排列(比如"10"排在"2"前面),保证月份按数字从小到大展示
内容的提问来源于stack exchange,提问作者RGR_288
相关产品推荐
相关产品推荐

