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

如何在ggplot2堆叠柱状图顶部添加整体误差棒(不使用dodge)

在堆叠柱状图顶部添加整体误差棒的解决方案

问题描述

我能找到分组(dodge)柱状图添加误差棒的示例,但想在堆叠柱状图的每个柱形顶部添加单个误差棒表示整体误差(类似目标图中的红色误差棒)。

我的基础ggplot2代码:

ggplot(sample, aes(x=strategy_short, y=baseline, fill=income)) +
  geom_bar(position="stack", stat="identity") +
  facet_grid(~scenario_capacity)

数据如下:

income,scenario_capacity,strategy_short,baseline,high,low
LIC,50_gb_month,4G_f,0.260317022,0.326222444,0.234391846
LIC,50_gb_month,5G_f,0.124212858,0.146834332,0.115607428
LIC,50_gb_month,4G_w,0.266087059,0.331992481,0.240156101
LIC,50_gb_month,5G_w,0.129977113,0.152604368,0.121371683
LMIC,50_gb_month,4G_f,0.83300281,0.981024297,0.770961424
LMIC,50_gb_month,5G_f,0.527561846,0.56027992,0.517383821
LMIC,50_gb_month,4G_w,0.837395381,0.985564298,0.77528317
LMIC,50_gb_month,5G_w,0.53198477,0.564819922,0.521741702
UMIC,50_gb_month,4G_f,2.084363642,2.161110527,2.047796949
UMIC,50_gb_month,5G_f,1.644845928,1.667321898,1.634737764
UMIC,50_gb_month,4G_w,2.08822286,2.165063696,2.051605578
UMIC,50_gb_month,5G_w,1.648696474,1.67124905,1.638559402
HIC,50_gb_month,4G_f,1.016843718,1.026058625,1.010465168
HIC,50_gb_month,5G_f,0.820046245,0.823345129,0.81792777
HIC,50_gb_month,4G_w,1.019669475,1.028904617,1.013290925
HIC,50_gb_month,5G_w,0.823000642,0.82634578,0.820861932

尝试用聚合后的DataFrame添加误差棒时,报错“object 'income' not found”,代码如下:

sample_short <- sample %>
  group_by(scenario_capacity, strategy_short) %>
  summarize(
    low = sum(low),
    baseline = sum(baseline),
    high = sum(high),
  )

ggplot(sample, aes(x=strategy_short, y=baseline, fill=income)) +
  geom_bar(position="stack", stat="identity") +
  geom_errorbar(data=sample_short, aes(y = baseline, ymin = low, ymax = high)) +
  facet_grid(~scenario_capacity)

问题原因

报错核心是全局ggplot映射包含fill=income,但聚合后的sample_short没有income列。geom_errorbar默认继承全局美学映射,会尝试寻找不存在的income列,从而触发错误。

解决方案

有两种简单有效的解决方法:

方法一:将fill映射移到geom_bar内部

把fill=income从全局aes中移除,仅放到geom_bar的aes里,避免geom_errorbar继承不必要的映射:

library(tidyverse)

# 修正聚合代码的管道符(原代码 %> 是 %>% 的笔误)
sample_short <- sample %>%
  group_by(scenario_capacity, strategy_short) %>%
  summarize(
    low = sum(low),
    baseline = sum(baseline),
    high = sum(high),
    .groups = "drop"  # 显式取消分组,避免后续警告
  )

ggplot(sample, aes(x=strategy_short, y=baseline)) +
  geom_bar(aes(fill=income), position="stack", stat="identity") +
  geom_errorbar(data=sample_short, aes(ymin = low, ymax = high), width=0.2) +  # width控制误差棒横向宽度
  facet_grid(~scenario_capacity)

方法二:给geom_errorbar设置inherit.aes=FALSE

强制geom_errorbar不继承全局美学映射,仅使用自身定义的映射:

library(tidyverse)

sample_short <- sample %>%
  group_by(scenario_capacity, strategy_short) %>%
  summarize(
    low = sum(low),
    baseline = sum(baseline),
    high = sum(high),
    .groups = "drop"
  )

ggplot(sample, aes(x=strategy_short, y=baseline, fill=income)) +
  geom_bar(position="stack", stat="identity") +
  geom_errorbar(
    data=sample_short, 
    aes(y = baseline, ymin = low, ymax = high), 
    width=0.2, 
    inherit.aes=FALSE  # 关键:不继承全局映射
  ) +
  facet_grid(~scenario_capacity)

两种方法都能成功在堆叠柱顶添加表示整体误差的误差棒,可根据个人习惯选择。


内容的提问来源于stack exchange,提问作者Thirst for Knowledge

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 20:55:37