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

在R语言中使用facet_grid时如何为堆叠柱状图添加正确误差棒

R语言堆叠柱状图分面后误差棒错位问题解决

问题描述

绘制堆叠柱状图并为每个堆叠柱添加误差棒时,单独筛选单个Treatment和Light子集绘制误差棒位置正确,但使用facet_grid后误差棒出现错位,数据集及原代码如下:

数据集

df=data.frame(
  cultivar = rep(c("CV1", "CV2"), each = 8L),
  part = rep(rep(c("DW1", "DW2"), 2), each = 4L),
  Light = rep(rep(c("Light1", "Light2"), 4), each = 2L),
  Treatment = rep(c("Treatment 1", "Treatment 2"), 8),
  DW_Mean = c(69.2825, 94.82, 57.8025, 90.7225, 26.6975, 37.3, 21.73, 28.3525, 58.825,
    79.45, 45.3225, 67.2425, 24.78, 32.2425, 16.8475, 24.9825
  ),
  DW_se = c(7.3890441138666, 12.3060777666972, 4.7905851678057, 5.91931355113637,
    5.10530830769961, 2.13571221531991, 1.87420205243014, 0.906838601957373,
    3.60502773914432, 7.59180918270913, 2.066044429177, 4.76078840634616,
    2.56271990926307, 1.23644904868741, 1.94433096891107, 2.04306295791393))

原代码

library(dplyr)
library(ggplot2)

dplyr::mutate(df, .by=cultivar, cume_y=cumsum(DW_Mean)) |>
     ggplot(aes(x=cultivar, y=DW_Mean, fill=part)) +
       geom_bar(stat="identity", position=position_stack(reverse=T), width=0.7, size=1) +
       geom_errorbar(aes(ymin=cume_y-DW_se, ymax=cume_y+DW_se),
                     position="identity", width=0.3) +
       scale_fill_manual(values = c("coral4", "grey45")) +
       scale_y_continuous(breaks = seq(0, 200, 50), limits = c(0, 200)) +
       facet_grid(~ Light ~ Treatment, scales = "free") +
       annotate("segment", x = 1, xend = 2, y = Inf, yend = Inf, color = "black", lwd = 1) +
       annotate("segment", y = 50, yend = 150, x = Inf, xend = Inf, color = "black", lwd = 1) +
       theme_classic(base_size = 18, base_family = "serif") +
       theme(legend.position = c(0.4, 0.9),
       legend.title = element_blank(),
       axis.line = element_line(linewidth = 0.5, colour = "black"),
       strip.background = element_rect(color = "white", linewidth = 0.5, linetype = "solid"))

问题原因

计算累积值cume_y时仅按cultivar分组,未考虑分面变量Light和Treatment,导致不同分面下的累积值被错误合并,进而造成误差棒位置错位。

解决方案

修改mutate的分组条件,将Light和Treatment也加入分组,确保每个分面内的堆叠累积值独立计算:

library(dplyr)
library(ggplot2)

# 调整分组条件,加入分面变量Light和Treatment
dplyr::mutate(df, .by=c(cultivar, Light, Treatment), cume_y=cumsum(DW_Mean)) |>
     ggplot(aes(x=cultivar, y=DW_Mean, fill=part)) +
       geom_bar(stat="identity", position=position_stack(reverse=T), width=0.7, size=1) +
       geom_errorbar(aes(ymin=cume_y-DW_se, ymax=cume_y+DW_se),
                     position="identity", width=0.3) +
       scale_fill_manual(values = c("coral4", "grey45")) +
       scale_y_continuous(breaks = seq(0, 200, 50), limits = c(0, 200)) +
       facet_grid(~ Light ~ Treatment, scales = "free") +
       annotate("segment", x = 1, xend = 2, y = Inf, yend = Inf, color = "black", lwd = 1) +
       annotate("segment", y = 50, yend = 150, x = Inf, xend = Inf, color = "black", lwd = 1) +
       theme_classic(base_size = 18, base_family = "serif") +
       theme(legend.position = c(0.4, 0.9),
             legend.title = element_blank(),
             axis.line = element_line(linewidth = 0.5, colour = "black"),
             strip.background = element_rect(color = "white", linewidth = 0.5, linetype = "solid"))

补充说明

  • 每个分面对应Light和Treatment的唯一组合,只有将这两个变量与cultivar共同作为分组依据,才能保证每个分面内的堆叠柱累积值计算准确,误差棒才能对应到正确的堆叠块顶部位置。
  • 代码中position_stack(reverse=T)反转了堆叠顺序,当前数据集的part顺序与反转后的堆叠顺序匹配,因此无需额外调整cumsum的排序逻辑。

内容的提问来源于stack exchange,提问作者J.K Kim

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 02:59:51