如何修正ggpattern柱状图仅部分柱子加图案时的图例错误
问题:ggpattern柱状图图例图案显示异常
使用ggpattern绘制柱状图时,指定仅为部分柱子添加图案(通过scale_pattern_manual),图表中的图案显示符合预期,但图例中所有柱子变量都显示条纹图案,如何修正?
解决方案
核心问题是图例的图案映射未与scale_pattern_manual的设置同步,通过调整刻度设置和自定义图例符号即可解决,修改后的完整代码如下:
library(data.table) library(ggpattern) library(ggplot2) mwe <- structure(list(time = c(2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024), variable = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L), levels = c("line", "colA", "colB", "colC", "colD"), class = "factor"), value = c(0.357009288818499, 1.71988206941869, 0.718233226499176, 0.731459804415735, 1.32156929908822, 0.560209948397006, 0.458172276280688, -0.545085303407777, 0.341824064319862, 0.548992565644735, 1.67689305057888, 0.731572600674735, 0.565083479982942, -1.50947739133498, 2.07670813142427, 1.05184988035862, -0.649722543167019, NA, -0.454897957364349, -0.560726446108042, -0.505986125219531, -0.436527260421888, 0.472106640040311, -0.55586138196329, -0.764628982718829, -0.402292611965036, -0.276831035898875, -0.0919962180055433, 0.198944308210276, 0.0475753047954131, 0.0408311042257559, 1.99036972882494, -1.3873165419347, -0.267642645661357, 0.0537581061845893, 0.0396657211136064, 0.354910898543741, 0.404771156737533, 0.445071446248599, 0.562072480628934, 0.368570321557913, 0.426679740870766, 0.438594024302237, 0.453171745539747, NA)), row.names = c(NA, -45L), class = c("data.table", "data.frame")) p <- ggplot(mapping = aes(y = value, x = time ) ) + geom_col_pattern(data = mwe[variable != "line"], aes(fill = variable, pattern = variable ), width = .8 ) + geom_line(data = mwe[variable == "line"], aes(color = variable), linewidth = 1 ) + geom_hline(yintercept = 0) + theme(axis.text.x = element_text(angle = 45, hjust=1)) + labs(x = NULL, y = "(%)") + scale_x_continuous(breaks = seq(min(mwe$time), max(mwe$time), by=2)) + scale_fill_manual(limits = c("colA", "colB", "colC", "colD", "line"), values = c("#005390", "#E75118", "#2F8CFF", "#FFC81D", "black"), labels = c("A", "B", "C", "D", "Line"), aesthetics = c("fill", "color") ) + # 同步刻度范围与fill一致,给无图案变量设NA并指定na.value scale_pattern_manual(limits = c("colA", "colB", "colC", "colD", "line"), values = c(NA, NA, "stripe", "crosshatch", NA), labels = c("A", "B", "C", "D", "Line"), na.value = "none" ) + # 自定义图例符号,区分线条和柱状图 guides(fill = guide_legend(nrow = 2, byrow = TRUE, key_glyph = function(data, params, size) { if (data$variable == "line") { draw_key_path(data, params, size) } else { draw_key_col_pattern(data, params, size) } }), pattern = "none") print(p)
关键修改说明
- 统一刻度映射范围:
- 将
scale_pattern_manual的limits扩展为包含所有变量,确保和scale_fill_manual的刻度范围完全匹配 - 给不需要图案的变量(
colA、colB、line)设置values = NA,并通过na.value = "none"指定无图案的显示规则
- 将
- 自定义图例符号:
- 在
guide_legend中添加key_glyph函数,分别为线条和柱状图指定对应的图例绘制函数,保证图例显示与实际图形一致
- 在
修改后,图例中的每个项会正确显示对应的图案(或无图案),和图表中的柱子显示保持同步。
内容的提问来源于stack exchange,提问作者gitcanzo
相关产品推荐
相关产品推荐

