如何为ggplot2的geom_bar()/geom_col()柱状图添加图案或纹理?
给ggplot2柱状图添加黑白友好的纹理/图案:更简便的方案
嘿,完全懂你的痛点!用scale_fill_grey()做的分组柱状图在黑白打印时辨识度真的拉胯,手动创建纹理又太折腾。这里有几个更通用、省心的思路,不用自己造轮子:
1. 用ggpattern包:一站式搞定图案填充
这是目前最省心的方案,专门为ggplot2设计的图案扩展包,内置了各种纹理(条纹、圆点、网格、波浪线等等),不用手动生成图案。
先安装包(如果没装的话):
install.packages("ggpattern")
然后修改你的代码,把geom_col()换成geom_col_pattern(),把图案映射到你的分组变量(这里是key):
library(ggplot2) library(dplyr, warn.conflicts=FALSE) library(tidyr) library(ggpattern) d <- iris %>% group_by(Species) %>% summarize_all(mean) %>% gather(key, val, -Species) ggplot(d, aes(x = Species, y = val, fill = key, pattern = key)) + geom_col_pattern( position = "dodge", pattern_fill = "black", # 图案颜色 pattern_color = "white", # 图案线条颜色(如果有的话) pattern_density = 0.2, # 图案密度,数值越小越稀疏 pattern_spacing = 0.05 # 图案间距 ) + scale_fill_grey() + scale_pattern_manual( # 自定义每个分组的图案类型 values = c("stripe", "circle", "grid") )
这个方法的好处是可视化区分度极高,而且图案类型可以自由搭配,完全适配黑白打印场景。
2. 用内置元素做标记:无需额外包
如果不想安装新包,可以用ggplot2自带的geom_text()或geom_point()给每个柱子添加独特标记,比如首字母、符号:
ggplot(d, aes(x = Species, y = val, fill = key)) + geom_col(position = "dodge") + geom_text( aes(label = substr(key, 1, 1)), # 取变量名首字母当标记 position = position_dodge(width = 0.9), # 和柱子对齐 color = "black", size = 4 ) + scale_fill_grey()
或者用不同形状的点:
ggplot(d, aes(x = Species, y = val, fill = key, shape = key)) + geom_col(position = "dodge") + geom_point( position = position_dodge(width = 0.9), color = "black", size = 3, y = -0.2 # 把点放在柱子下方,避免遮挡 ) + scale_fill_grey() + scale_shape_manual(values = c(16, 17, 18))
这种方法的优势是轻量、无需额外依赖,适合快速调整。
3. 调整边框样式:用线型区分分组
另一种无依赖的思路是给不同分组的柱子设置不同的边框线型(实线、虚线、点线),结合灰度填充:
ggplot(d, aes(x = Species, y = val, fill = key, linetype = key)) + geom_col(position = "dodge", color = "black", size = 1) + scale_fill_grey() + scale_linetype_manual(values = c("solid", "dashed", "dotted"))
这种方法在黑白打印时也能清晰区分不同组,而且视觉上不会太杂乱。
总结
- 追求直观和丰富性:优先选
ggpattern,图案类型多,效果最好; - 不想加包:用文本/形状标记,或者边框线型调整,简单高效;
这些方案都比手动创建纹理要省心得多,完全适配黑白打印的需求!
内容的提问来源于stack exchange,提问作者Joshua Rosenberg
相关产品推荐
相关产品推荐

