如何在ggplot图例中为单个标签配置多个颜色符号?
解决方案:为ggplot图例单个标签配置多颜色符号
需求说明
要绘制3个站点响应随年份变化的堆叠条形图,按Site分面,每个分面使用不同配色;当前通过拼接Site和Type生成Col_Var实现了分面配色,但图例条目过多(6个),希望简化为2个标签:Type A对应3个深色方块,Type B对应3个浅色方块。
实现思路
核心是拆分颜色映射逻辑:
- 保留
Type作为图例的分组依据,让图例只显示Type A和Type B两个标签 - 用
Site区分同类型下的不同配色,手动指定颜色实现深浅分组 - 利用
guide_legend()的override.aes参数,为每个图例标签设置多个颜色符号
修改后的代码
library(ggplot2) # 生成示例数据 Plot_df <- data.frame( Site = rep(c("Site A","Site B","Site C"), each = 10), Type = rep(c("Type A","Type B"), times = 15), Year = rep(rep(seq(2010,2014,1), each=2), times=3), Value = rnorm(30, mean=50, sd=10) ) # 按Type分组定义颜色:Type A对应3个深色,Type B对应3个浅色 Stacked_Plot_Colours <- c( "Site A-Type A" = "#027E5D", "Site A-Type B" = "#89EFC7", "Site B-Type A" = "#6F2D01", "Site B-Type B" = "#F5773A", "Site C-Type A" = "#3A3663", "Site C-Type B" = "#8F8ACD" ) Stacked_Plot <- ggplot(Plot_df) + geom_bar( aes(x = as.factor(Year), y = Value, fill = interaction(Site, Type)), # 用interaction替代手动拼接的Col_Var position = "stack", stat = "identity" ) + facet_wrap(~ Site, ncol=1) + scale_fill_manual( values = Stacked_Plot_Colours, # 将图例标签重映射为Type labels = function(x) gsub(".*-", "", x), # 自定义图例:为每个Type标签设置多个颜色符号 guide = guide_legend( override.aes = list( fill = list( c("#027E5D", "#6F2D01", "#3A3663"), # Type A的3个深色 c("#89EFC7", "#F5773A", "#8F8ACD") # Type B的3个浅色 ) ), title = NULL # 隐藏图例标题 ) ) + theme( legend.position = "top", panel.grid.major = element_blank(), panel.grid.minor = element_blank(), panel.background = element_blank(), axis.line = element_line(colour = "black") ) Stacked_Plot
关键说明
- 颜色映射优化:用
interaction(Site, Type)替代手动拼接的Col_Var,更规范地生成分组变量 - 标签重命名:通过
labels = function(x) gsub(".*-", "", x)把Site-Type格式的标签简化为只显示Type - 图例自定义:
guide_legend(override.aes = list(fill = list(...)))为每个图例标签(Type A/B)指定对应的多个颜色,实现单个标签旁显示多颜色符号的效果
内容的提问来源于stack exchange,提问作者James White
相关产品推荐
相关产品推荐

