如何在ggplot图例中控制颜色、填充与线型(含模型基准线)
解决ggplot2图例同时显示模型颜色与线型的问题
问题背景
我有两个模型的结果数据,包含分位数阴影展示的变异情况,每个模型还对应一条无变异的参考基准线。示例数据生成代码如下:
# 创建数据 y <- 1+0.1*c(0:29) r1 <- runif(30,0.8,1.2) mydata0 <- data.frame(model = "model1",scenario="a_sc1", year = c(2022:2051), q9 = y+2*r1, q7=y+r1, q5=y+r1-1,q3=y-r1,q1=y-2*r1,bench= r1) mydata1 <- mydata0 mydata1[,4:9] <- r1+mydata1[,4:9] mydata1$model <- "model2" mydata <- rbind(mydata0, mydata1)
第一次绘图尝试:图例缺失基准线线型
图形效果符合需求,但图例里没有显示基准线的虚线标识:
library(ggplot2) col2 <- c("darkred","steelblue") col2f <- c("magenta","green") ggplot(data=mydata, aes(x=year, group=model)) + geom_ribbon(aes(ymin=q1 , ymax=q9,fill=model), linetype=0, alpha=0.2) + geom_ribbon(aes(ymin=q3 , ymax=q7,fill=model), linetype=0, alpha=0.2) + geom_line(aes(x=year, y=q5 ,color=model), linetype=1, size=1.3)+ geom_line(aes(x=year, y=bench ,color=model), linetype=2, size=1.3)+ scale_color_manual(values = col2) + scale_fill_manual(values = col2f)+ scale_linetype_manual(values = c(1,2)) + labs( y = "var [mg/l]", x="") + theme_light() + theme(text = element_text(size = 18),axis.text=element_text(colour="black",size=20),legend.text=element_text(size=22))
第二次绘图尝试:长格式数据,图例缺失对应颜色
转换为长格式数据后,图例显示了线型,但基准线没有对应模型的颜色:
# 长格式数据转换 mydata2 <- rbind(mydata[,-9], data.frame(model=mydata$model,scenario="bench",year=mydata$year,q9=NA,q7=NA,q5=mydata$bench,q3=NA,q1=NA)) ggplot(data=mydata2, aes(x=year)) + geom_ribbon(aes(ymin=q1 , ymax=q9,fill=model), linetype=0, alpha=0.2, na.rm = TRUE) + geom_ribbon(aes(ymin=q3 , ymax=q7,fill=model), linetype=0, alpha=0.2, na.rm = TRUE) + geom_line(aes(x=year, y=q5 ,color=model, linetype=scenario), size=1.3)+ scale_color_manual(values = col2) + scale_fill_manual(values = col2f)+ labs( y = "var [mg/l]", x="") + theme_light() + theme(text = element_text(size = 18),axis.text=element_text(colour="black",size=20),legend.text=element_text(size=22))
期望的图例效果是:每个模型对应两个条目(实线预测线、虚线基准线),且颜色与模型本身的颜色一致。
解决方案
方案1:基于原始宽格式数据调整
通过将线型映射为自定义标签,并修改图例的覆盖属性,实现颜色与线型的统一展示:
library(ggplot2) col2 <- c("darkred","steelblue") col2f <- c("magenta","green") ggplot(data=mydata, aes(x=year, group=model)) + # 绘制分位数阴影 geom_ribbon(aes(ymin=q1 , ymax=q9,fill=model), linetype=0, alpha=0.2) + geom_ribbon(aes(ymin=q3 , ymax=q7,fill=model), linetype=0, alpha=0.2) + # 绘制预测线,将linetype映射为自定义标签 geom_line(aes(x=year, y=q5 ,color=model, linetype="预测线"), size=1.3)+ # 绘制基准线,同样映射linetype geom_line(aes(x=year, y=bench ,color=model, linetype="基准线"), size=1.3)+ # 设置颜色、填充、线型的手动映射 scale_color_manual(values = col2, name="模型") + scale_fill_manual(values = col2f, name="模型") + scale_linetype_manual(values = c("预测线"=1, "基准线"=2), name="线类型") + # 合并图例,让颜色和线型在同一个图例中显示 guides( color = guide_legend( override.aes = list(linetype = c(1, 1, 2, 2)), keywidth = unit(2, "cm") ), fill = guide_legend(order = 1), linetype = "none" ) + labs( y = "var [mg/l]", x="") + theme_light() + theme( text = element_text(size = 18), axis.text=element_text(colour="black",size=20), legend.text=element_text(size=22) )
方案2:基于长格式数据调整
如果偏好长格式数据,只需通过guide_legend的override.aes参数为线型图例添加对应模型颜色:
ggplot(data=mydata2, aes(x=year)) + geom_ribbon(aes(ymin=q1 , ymax=q9,fill=model), linetype=0, alpha=0.2, na.rm = TRUE) + geom_ribbon(aes(ymin=q3 , ymax=q7,fill=model), linetype=0, alpha=0.2, na.rm = TRUE) + geom_line(aes(x=year, y=q5 ,color=model, linetype=scenario), size=1.3)+ scale_color_manual(values = col2, name="模型") + scale_fill_manual(values = col2f, name="模型") + scale_linetype_manual(values = c("a_sc1"=1, "bench"=2), name="线类型") + guides( linetype = guide_legend( override.aes = list(color = rep(col2, each=2)) ) ) + labs( y = "var [mg/l]", x="") + theme_light() + theme(text = element_text(size = 18),axis.text=element_text(colour="black",size=20),legend.text=element_text(size=22))
内容的提问来源于stack exchange,提问作者Shajar
相关产品推荐
相关产品推荐

