You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 23:18:11