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

为含多响应变量的比例堆叠柱状图添加顶部总计

问题:为堆叠比例柱状图添加总计失败,计数版本可正常显示(含警告)

尝试为x、y均为多响应变量的堆叠比例柱状图添加总计,计数版本的图表虽有警告但成功添加了总计,然而比例版本的图表添加总计完全失败。

数据集片段

structure(list(HNV_grasslands = c(1L, 0L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L), HNV_arable = c(1L, 1L, 1L, 0L, 0L, 1L, 1L, 1L, 
1L, 1L, 1L), HNV_permanent_crop = c(1L, 1L, 1L, 0L, 0L, 1L, 1L, 
1L, 1L, 1L, 1L), HNV_mosaic = c(1L, 0L, 1L, 0L, 0L, 0L, 1L, 1L, 
1L, 0L, 1L), Animal_vegetal = c("", "Both", "Both", "Both", "", 
"Vegetal species", "Vegetal species", "", "Both", "Animal species", 
"Both")), row.names = 10:20, class = "data.frame")

计数版本代码(含警告但可显示总计)

警告信息

The following aesthetics were dropped during statistical transformation: fill This can happen when ggplot fails to infer the correct grouping structure in the data. Did you forget to specify a group aesthetic or to convert a numerical variable into a factor?

代码

hnvf4 <- hnvf3 %>%
  pivot_longer(
    cols = starts_with("HNV"),
    names_to = c("HNV"),
    names_prefix = "HNV_",
    values_to = "value1") |>
    filter(value1 == 1 & Animal_vegetal !="") |>
  select(-value1) # 移除value1,避免数据全为1的情况
glimpse(hnvf4)

hnvf4 |>
  ggplot(aes(x = HNV,fill = factor(Animal_vegetal, levels=c("Animal species", "Vegetal species", "Both")))) +
  geom_bar()+
  geom_text(stat ="count",aes(label=after_stat(count), group= HNV, vjust= -1))+
    scale_fill_manual(values = c("#FDCDAC", "#B3E2CD","#CBD5E8"))+
  theme(axis.text.x = element_text(angle=90, vjust = 0.5, hjust=1), 
        axis.ticks.x = element_blank())+
  theme(axis.line.y = element_line(linewidth = 0.5, colour = "black"),
        axis.ticks.length.y.left = unit(.25, "cm"))+
  theme(panel.background = element_rect(fill=NA))+
  scale_x_discrete(labels=c('arable land', 'grasslands', 'mosaic landscape', 
                            'permanent croplands')) +
  labs(x= "HNV farmland type", y="Number of studies", fill= "")+
  theme(axis.title.y = element_text(margin=margin(r= 15)))+
  scale_y_continuous(limits= c(0,100), breaks=c(0,25,50,75, 100),expand = c(0,0)) +
  theme(legend.position = c(.99, .95),
        legend.justification = c("right", "top"))

比例版本代码(无法添加总计)

hnvf4%>%
  ggplot(aes(x = HNV,fill = factor(Animal_vegetal,levels=c("Animal species", "Vegetal species", "Both")))) +
  geom_bar(position="fill")+
  #geom_text(stat ="count",aes(label=after_stat(count), group= HNV, vjust= -1))+
  scale_fill_manual(values = c("#FDCDAC", "#B3E2CD","#CBD5E8"))+
  theme(axis.text.x = element_text(angle=90, vjust = 0.5, hjust=1), 
        axis.ticks.x = element_blank())+
  theme(axis.line.y = element_line(linewidth = 0.5, colour = "black"),
        axis.ticks.length.y.left = unit(.25, "cm"))+
  theme(panel.background = element_rect(fill=NA))+
  scale_x_discrete(labels=c('arable land', 'grasslands', 'mosaic landscape', 
                            'permanent croplands')) +
  labs(x= "HNV farmland type", y="Proportion of studies", fill= "")+
  theme(axis.title.y = element_text(margin=margin(r= 15)))+
  # 移除y轴额外空白,让y轴从0开始
  scale_y_continuous(expand = c(0,0))

解决方案

比例版本的核心问题在于position="fill"将y轴转换为0-1的比例区间,直接使用stat="count"会因分组和坐标映射冲突导致总计无法正确显示。最稳妥的方式是提前计算每个HNV类别的总计数,再将总计文本映射到比例轴上方:

步骤1:计算总计数

# 统计每个HNV类型的有效样本总数
total_counts <- hnvf4 %>%
  group_by(HNV) %>%
  summarise(total = n(), .groups = "drop")

步骤2:修改比例图表代码,添加总计

hnvf4 %>%
  ggplot(aes(x = HNV, fill = factor(Animal_vegetal, levels=c("Animal species", "Vegetal species", "Both")))) +
  geom_bar(position="fill") +
  # 添加总计文本,使用提前计算的总计数数据集
  geom_text(data = total_counts, aes(x = HNV, y = 1.05, label = total, fill = NULL), 
            size = 3.5, vjust = 0) +
  scale_fill_manual(values = c("#FDCDAC", "#B3E2CD","#CBD5E8")) +
  theme(axis.text.x = element_text(angle=90, vjust = 0.5, hjust=1), 
        axis.ticks.x = element_blank()) +
  theme(axis.line.y = element_line(linewidth = 0.5, colour = "black"),
        axis.ticks.length.y.left = unit(.25, "cm")) +
  theme(panel.background = element_rect(fill=NA)) +
  scale_x_discrete(labels=c('arable land', 'grasslands', 'mosaic landscape', 
                            'permanent croplands')) +
  labs(x= "HNV farmland type", y="Proportion of studies", fill= "") +
  theme(axis.title.y = element_text(margin=margin(r= 15))) +
  # 扩展y轴上限,确保总计文本能完整显示
  scale_y_continuous(expand = c(0,0), limits = c(0, 1.1)) +
  theme(legend.position = c(.99, .95),
        legend.justification = c("right", "top"))

说明

  • 提前计算总计数可以避免ggplot统计变换时的分组歧义,确保总计数值准确。
  • 将y=1.05设置在比例轴(0-1)上方,配合scale_y_continuous(limits = c(0, 1.1))扩展y轴范围,保证总计文本不被截断。
  • 设置fill = NULL避免继承主图的fill美学,防止出现不必要的分组警告。

内容的提问来源于stack exchange,提问作者elsich

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 05:25:18