如何为ggplot2图表fill分组添加指定图案并保留原有颜色
问题解决:ggplot2为不同类别柱状图添加独特图案并保留颜色
需求:为数据集splt列的4个类别分别设置独特填充图案(类别1=hexagons、类别2=crosshatch、类别3=right45、类别4=checkerboard),同时保留原柱状图的颜色区分,且显示误差线和标注文本。
原代码问题分析
- 重复使用
geom_bar()和geom_bar_pattern(),导致两层柱状图重叠,图案层覆盖颜色层 geom_bar_pattern()固定fill='white',破坏了原有的颜色映射- 未将
pattern_type与splt变量关联,图案设置未生效 - 图层顺序错误,误差线和文本被柱状图遮挡
修正后的完整代码
library(ggplot2) library(ggpattern) library(tidyverse) # 数据集 data <- structure(list(trt = c("t1", "t1", "t1", "t1", "t2", "t2", "t2", "t2", "t3", "t3", "t3", "t3", "t4", "t4", "t4", "t4"), splt = c(1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4), response = c(82, 62, 17, 93, 55, 99, 42, 67, 56, 8, 62, 69, 38, 80, 86, 26), standard_error = c(2, 5, 3, 3, 1, 4, 4, 6, 4, 4, 1, 5, 5, 5, 6, 4), hsd = c("abcdef", "abcdef", "abcdefg", "abcdefg", "abcdefgh", "abcdefgh", "abcdefgh", "abcdefgh", "abcdefgh", "abcdefgh", "abcdefgh", "abcdefgh", "abcdefgh", "abcdefgh", "abcdefgh", "abcdefgh")), class = "data.frame", row.names = c(NA, -16L)) # 文本换行函数 fun <- function(string, dist = 3){ left <- substr(string, 1, dist) right <- substr(string, dist+1, nchar(string)) paste0(left, "\n", right) } # 转换为因子 data$splt <- as.factor(data$splt) ggplot(data, aes(x = trt, y = response, fill = splt, pattern_type = splt)) + # 使用geom_bar_pattern替代原geom_bar,同时实现颜色和图案映射 geom_bar_pattern( stat = "identity", width = 0.6, position = position_dodge(width = 0.8), colour = "black", pattern_scale = 3, pattern_aspect_ratio = 1, pattern_key_scale_factor = 1.5 ) + # 误差线,保持与柱状图相同的position_dodge参数 geom_errorbar(aes(ymin = response, ymax = response + standard_error), width = 0.3, position = position_dodge(0.8)) + # 文本标注 geom_text(aes(label = fun(hsd), y = response + standard_error, group = splt), vjust = -0.9, size = 4, position = position_dodge(width = 0.8)) + # 设置图案映射 scale_pattern_type_manual( name = "Splt", values = c(`1` = 'hexagons', `2` = 'crosshatch', `3` = 'right45', `4` = 'checkerboard') ) + # 保留原颜色映射(ggplot默认配色) scale_fill_discrete(name = "Splt") + # 图形标签和主题设置 xlab("Treatment") + ylab('Response') + ggtitle("Title", subtitle = "Subtitle") + theme( plot.title = element_text(hjust=0.5, size = 15), plot.subtitle = element_text(hjust=0.5, size = 11), axis.text = element_text(size = 10), axis.title = element_text(size = 12), legend.key.size = unit(1.5, 'cm') ) + ylim(0, 118)
关键修改说明
- 合并柱状图层:移除原
geom_bar(),用geom_bar_pattern()同时实现颜色(fill=splt)和图案(pattern_type=splt)的映射,避免图层重叠。 - 关联图案与类别:在
ggplot()的aes中添加pattern_type = splt,让图案随splt类别变化。 - 保留颜色映射:删除
geom_bar_pattern()中固定的fill='white',保留fill=splt的颜色区分。 - 统一对齐参数:所有需要分组的元素(柱状图、误差线、文本)使用相同的
position_dodge(width=0.8),确保对齐。 - 调整图例:通过
scale_pattern_type_manual和scale_fill_discrete统一图例名称,避免重复图例。
内容的提问来源于stack exchange,提问作者sneeze_shiny
相关产品推荐
相关产品推荐

