使用ggplot2与ggpattern时的条形图排列及图例优化问题
解决ggplot2+ggpattern条形图的几个问题
核心需求与问题点
- 用填充色区分destination,图案区分origin
- 条形按destination分组,同颜色(同destination)的条形相邻排列
- destination图例仅显示纯色,避免图案误导
- 处理同一年份不同destination存在正负flow时的重叠/显示问题
修改后的完整代码
# 加载所需包 library(tibble) library(ggplot2) library(ggpattern) # 示例数据 data <- tibble::tribble(~time, ~origin, ~destination, ~flow, "2015", "BRA", "CHN", 57, "2016", "BRA", "CHN", -70, "2015", "BRA", "USA", 88, "2016", "BRA", "USA", 200, "2015", "MEX", "CHN", 99, "2016", "MEX", "CHN", 70, "2015", "MEX", "USA", 50, "2016", "MEX", "USA", 100, ) # 生成分组变量:把年份和目的地拼接,确保同目的地的条形相邻 data$group_var <- paste(data$time, data$destination, sep = "_") # 绘图 ggplot(data, aes(x = group_var, fill = destination)) + # 拆分正负流量分别绘制,避免互相覆盖 geom_col_pattern(aes(y = ifelse(flow >= 0, flow, 0), pattern = origin), col = "black", pattern_colour = "grey", pattern_spacing = 0.05, pattern_density = 0.09, pattern_key_scale_factor = 0.5) + geom_col_pattern(aes(y = ifelse(flow < 0, flow, 0), pattern = origin), col = "black", pattern_colour = "grey", pattern_spacing = 0.05, pattern_density = 0.09, pattern_key_scale_factor = 0.5) + # 把x轴标签还原为年份,去掉拼接的目的地后缀 scale_x_discrete(labels = gsub("_.*", "", unique(data$group_var))) + # 自定义图例:强制目的地图例只显示纯色 guides( fill = guide_legend(override.aes = list(pattern = "none")), pattern = guide_legend(title = "Origin") ) + # 按目的地分面,让同颜色条形集中展示,同时区分不同目的地 facet_wrap(~destination, scales = "free_x", nrow = 1) + labs(x = "年份", y = "流量") + theme_bw()
关键修改说明
1. 实现同destination条形相邻
- 生成
group_var变量,将年份和目的地拼接,让同一年份下的同目的地数据归为一组 - 用
facet_wrap(~destination, scales = "free_x", nrow = 1)按目的地分面,既保证同颜色条形相邻,又能清晰区分不同目的地的流量数据
2. 修正destination图例显示
- 通过
guides(fill = guide_legend(override.aes = list(pattern = "none")))强制去掉目的地图例中的图案,只保留纯色,避免误导
3. 处理正负flow的重叠问题
- 拆分正负流量分别绘制:用
ifelse把flow拆分为正值和负值,分别调用geom_col_pattern,让正负条形在y轴上下分开显示,不会互相覆盖
4. 优化x轴标签
- 用
scale_x_discrete配合gsub把拼接的group_var标签还原为纯年份,保持x轴简洁易读
内容的提问来源于stack exchange,提问作者Marie Veit
相关产品推荐
相关产品推荐

