ggplot柱状图误差线对齐、图例优化及堆叠图实现问题
问题解决方案
1. 误差线与柱状图对齐修复
误差线错位的核心原因是:geom_errorbar没有继承pattern=treated的分组逻辑,且stat_summary的使用冗余(你的数据已是均值,无需再计算均值)。修正步骤:
- 将
pattern=treated放入全局aes,让柱状图和误差线共用同一分组规则 - 统一
position_dodge的宽度参数(保持0.9),确保两者对齐 - 替换
stat_summary为geom_bar_pattern(stat="identity"),直接使用现有数据
2. 图例优化
当前图例无明确说明,需给scale_pattern_manual添加名称和对应标签,同时隐藏多余的填充图例:
- 设置图例名称为「处理状态」,明确对应「未处理/处理」的图案样式
- 用
scale_fill_identity直接使用数据中的颜色值,避免生成无效的填充图例
3. 分面内堆叠柱状图实现
堆叠需要将position改为position_stack(),同时调整x轴分组为models(同一x类别下堆叠不同处理组),误差线需用position_stack(vjust=0.5)居中显示在堆叠段上方。
修正后的分组柱状图代码(对齐+图例优化)
library(ggplot2) library(tidyverse) library(ggpattern) models = c("a", "b") task = c("1","2") ratios = c(0.3, 0.4) standard_errors = c(0.02, 0.02) colors = c("#F39B7FFF", "#8491B4FF") # 整理数据(简化流程) df <- data.frame(task = task, ratios = ratios) %>% mutate(filler = 1 - ratios) %>% gather(key = "obs", value = "ratios", -1) %>% mutate(upper = ratios + rep(standard_errors, 2), lower = ratios - rep(standard_errors, 2), models = rep(models, 2), col = rep(colors, 2), # 明确处理组标签 treated = ifelse(ratios < 0.5, "未处理(not treated)", "处理(treated)")) # 对齐后的分组柱状图 p_aligned <- ggplot(df, aes(x = models, y = ratios, fill = col, pattern = treated, ymin = lower, ymax = upper)) + geom_bar_pattern(stat = "identity", position = position_dodge(width = 0.9), pattern_fill = "black", colour = "black") + geom_errorbar(position = position_dodge(width = 0.9), width = 0.2) + scale_pattern_manual(name = "处理状态", values = c("未处理(not treated)" = "none", "处理(treated)" = "stripe")) + scale_fill_identity() + # 直接使用数据中的颜色 facet_grid(.~task, scales = "free_x", space = "free_x", switch = "x") + labs(x = "模型", y = "比例") p_aligned
分面内堆叠柱状图代码
# 堆叠版本 p_stacked <- ggplot(df, aes(x = models, y = ratios, fill = treated, pattern = treated)) + geom_bar_pattern(stat = "identity", position = position_stack(), pattern_fill = "black", colour = "black") + # 误差线居中显示在堆叠段上方 geom_errorbar(aes(ymin = lower, ymax = upper), position = position_stack(vjust = 0.5), width = 0.2) + scale_pattern_manual(name = "处理状态", values = c("未处理(not treated)" = "none", "处理(treated)" = "stripe")) + scale_fill_manual(name = "处理状态", values = c("未处理(not treated)" = "#F39B7FFF", "处理(treated)" = "#8491B4FF")) + facet_grid(.~task, scales = "free_x", space = "free_x", switch = "x") + labs(x = "模型", y = "比例") p_stacked
内容的提问来源于stack exchange,提问作者Tamay
相关产品推荐
相关产品推荐

