ggplot2中合并两种不同美学映射的图例失败求助
解决ggplot2中合并fill与colour图例的问题
嘿,我来帮你搞定这个图例合并的问题!你遇到的核心问题是:fill映射的是Specimen,而colour映射的是bar——这两个变量的级别没有直接对应关系,所以ggplot会默认生成两个独立的图例。要合并它们,我们需要让这两个美学属性的图例条目一一绑定,或者统一映射到同一个变量上。下面是两种可行的解决方案:
方案一:统一映射到同一个变量(推荐)
把colour也映射到Specimen,然后针对每个Specimen对应的bar值,单独设置边框颜色。这样fill和colour都关联到同一个变量,ggplot会自动合并它们的图例:
library(ggplot2) x <- data.frame(Specimen=c("A","B","C","D"), Value=rep(0.5,4), Type=c("c1","c1","c2","c2"), Treatment=factor(rep("A", 4)), bar=c("hot", "cold", "cold", "cold")) list2env(split(x, x$Type), envir = .GlobalEnv) # 定义每个Specimen对应的填充色和边框色 fill_palette <- c("A" = "gold", "B" = "green") color_palette <- c("A" = "gray40", "B" = "black") # A对应hot的灰色,B对应cold的黑色 p1 <- ggplot() + geom_bar(data=c1, aes(x = Treatment, y = Value, fill = Specimen, colour = Specimen), stat="identity", position="fill", width=0.5) + scale_fill_manual("Specimen", values = fill_palette) + scale_color_manual("Specimen", values = color_palette) + scale_y_continuous(expand = c(0, 0)) # 补全你之前没写完的expand参数 print(p1)
方案二:手动覆盖图例属性(保留原映射)
如果你坚持要保留colour=bar的映射,可以手动在guides里给fill图例的每个条目加上对应的边框颜色,同时隐藏独立的colour图例:
p2 <- ggplot() + geom_bar(data=c1, aes(x = Treatment, y = Value, fill = Specimen, colour=bar), stat="identity", position="fill", width=0.5) + scale_fill_manual("", values=c("gold", "green"), breaks = c("A", "B")) + scale_color_manual("", values=c("gray40","black"), breaks = c("hot", "cold")) + scale_y_continuous(expand = c(0, 0)) + guides( fill = guide_legend(override.aes = list(colour = c("gray40", "black"))), # 给每个填充条目加对应边框色 colour = "none" # 隐藏单独的边框图例 ) print(p2)
关键原理说明
要合并不同美学属性的图例,必须满足两个核心条件:
- 两个美学对应的
scale要有相同的名称(比如都设为"Specimen"或空字符串); - 图例条目要一一对应——要么映射到同一个变量,要么手动指定每个条目对应的另一种美学属性。
内容的提问来源于stack exchange,提问作者nouse
相关产品推荐
相关产品推荐

