如何用ggplot2创建带总计列与百分比标签的堆叠条形图?
同时实现堆叠条形图的总计列与百分比标签
问题描述
我想要制作一个带有总计列和每个条形内百分比标签的堆叠条形图,但目前只能单独实现其中一项功能,希望得到帮助以同时实现这两个需求。
数据片段
structure(list(SPTOT = c(2L, 6L, 5L, 5L, 4L, 4L, 4L, 3L, 2L, 2L, 2L, 3L, 4L, 2L, 5L, 2L, 3L, 4L, 4L, 4L), CASE = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L), case1 = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L), levels = c("1", "2", "3", "4"), class = "factor"), case2 = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L), levels = c("Bierge", "Santa Creu", "Collbató", "Monells"), class = "factor"), sptot1 = structure(c(2L, 6L, 5L, 5L, 4L, 4L, 4L, 3L, 2L, 2L, 2L, 3L, 4L, 2L, 5L, 2L, 3L, 4L, 4L, 4L), levels = c("1", "2", "3", "4", "5", "6"), class = "factor"), sptot2 = c("50-100 Ha", "> 500 Ha", "> 500 Ha", "> 500 Ha", "201-500 Ha", "201-500 Ha", "201-500 Ha", "101-200 Ha", "50-100 Ha", "50-100 Ha", "50-100 Ha", "101-200 Ha", "201-500 Ha", "50-100 Ha", "> 500 Ha", "50-100 Ha", "101-200 Ha", "201-500 Ha", "201-500 Ha", "201-500 Ha")), row.names = c(NA, 20L), class = "data.frame")
单独实现的代码
带总计列的比例堆叠条形图
farm_size1 %>% ggplot(aes(x=case2)) + geom_bar(aes(fill=sptot2), position="fill")+ geom_bar(aes(x="Total", fill=sptot2), position= "fill")+ scale_y_continuous(expand = c(0,0), labels = c("0", "25", "50", "75", "100"))+ scale_fill_manual(values=c("#FB8072","#FBB4AE","#FDB462", "#2a7dad","#8DD3C7","#E6F5C9"), labels=c("< 50 Ha", "50-100 Ha", "101-200 Ha", "201-500 Ha", "> 500 Ha"))+ labs(x= "", y="Percentage", fill= "Farm size")
带百分比标签的堆叠条形图
farm_size1 %>% count(case2, sptot2)%>% group_by(case2)%>% mutate(pct=prop.table(n)*100)%>% ggplot()+ aes(case2, pct, fill=sptot2)+ geom_bar(stat = "identity")+ ylab("Percentage of farms") + geom_text(aes(label=paste0(sprintf("%1.1f", pct),"%")), position=position_stack(vjust=0.5), size=3)+ scale_fill_manual(values=c("#FB8072","#FBB4AE","#FDB462", "#2a7dad","#8DD3C7","#E6F5C9"), labels=c("< 50 Ha", "50-100 Ha", "101-200 Ha", "201-500 Ha", "> 500 Ha"))
合并解决方案
要同时实现两个功能,需提前计算**所有分组(包括总计)**的百分比,再统一绘制:
library(dplyr) library(ggplot2) # 1. 计算各地区分组的数量与百分比 region_data <- farm_size1 %>% count(case2, sptot2) %>% group_by(case2) %>% mutate(pct = prop.table(n) * 100) %>% ungroup() # 2. 计算总计分组的数量与百分比 total_data <- farm_size1 %>% count(sptot2) %>% mutate(case2 = "Total", pct = prop.table(n) * 100) %>% select(case2, sptot2, n, pct) # 3. 合并地区数据与总计数据 combined_data <- bind_rows(region_data, total_data) # 4. 绘制带总计列和百分比标签的堆叠条形图 ggplot(combined_data, aes(x = case2, y = pct, fill = sptot2)) + geom_bar(stat = "identity") + # 添加居中的百分比标签 geom_text(aes(label = paste0(sprintf("%1.1f", pct), "%")), position = position_stack(vjust = 0.5), size = 3) + # 设置y轴为0-100的百分比格式 scale_y_continuous(expand = c(0, 0), limits = c(0, 100), labels = function(x) paste0(x, "%")) + # 自定义填充色和图例标签 scale_fill_manual(values = c("#FB8072","#FBB4AE","#FDB462", "#2a7dad","#8DD3C7","#E6F5C9"), labels = c("< 50 Ha", "50-100 Ha", "101-200 Ha", "201-500 Ha", "> 500 Ha")) + labs(x = "", y = "Percentage", fill = "Farm size") + theme_minimal()
关键说明
- 提前统一计算所有分组的百分比,确保标签能精准对应每个堆叠块
position_stack(vjust=0.5)让标签居中显示在每个条形段内- 统一设置y轴范围和格式,与原有图表风格保持一致
内容的提问来源于stack exchange,提问作者elsich
相关产品推荐
相关产品推荐

