ggplot合并不同数据集图例:消除空白及更优实现方案
解决ggplot2组合图的图例空白问题及优化实现方式
一、更简便的实现方式:直接在主图中合并图例
不需要拆分提取图例再拼接,直接在主图中统一设置美学映射,让ggplot自动合并图例,这是最直接的解决方案:
library(ggplot2) library(cowplot) # 数据集 d1 <- data.frame(x=c(0,5,8),y=c(1.2,5.5,8),ymin=c(1.2,5.5,8)-1,ymax=c(1.2,5.5,8)+1,col=factor("Data1")) d2 <- data.frame(x=0:9,y=1+0:9,ymin=0.5+0:9,ymax=1.5+0:9,col=factor("Data2")) # 主图直接合并图例 ggplot() + # Data2的ribbon和line,映射fill和col到col变量 geom_ribbon(data = d2, aes(x=x, y=y, ymin=ymin, ymax=ymax, fill=col), alpha=0.1) + geom_line(data=d2, aes(x=x, y=y, col=col), size=1) + # Data1的pointrange,映射col和fill到col变量 geom_pointrange(data=d1, aes(x=x, y=y, ymin=ymin, ymax=ymax, col=col, fill=col), linewidth=1, size=0.5) + # 手动设置颜色和填充值,统一图例名称为空 scale_color_manual(name="", values=c("Data1"="darkred", "Data2"="black")) + scale_fill_manual(name="", values=c("Data1"="darkred", "Data2"="black")) + # 可选:调整图例位置到底部,适配布局 theme(legend.position = "bottom")
ggplot会自动将col和fill的图例合并(因为它们的名称、分类完全匹配),彻底避免拆分拼接带来的空白问题。
二、消除原有方法中的图例空白
如果坚持使用拆分提取图例的方式,空白来自于get_legend提取的图例对象内部仍有默认边距,只需调整图例的内部主题参数即可消除:
library(ggplot2) library(cowplot) # 数据集 d1=data.frame(x=c(0,5,8),y=c(1.2,5.5,8),ymin=c(1.2,5.5,8)-1,ymax=c(1.2,5.5,8)+1,col=factor("Data1")) d2=data.frame(x=0:9,y=1+0:9,ymin=0.5+0:9,ymax=1.5+0:9,col=factor("Data2")) # 主图 plot = ggplot()+ geom_ribbon(data = d2, aes(x=x,y=y,ymin=ymin,ymax=ymax), fill="black", alpha=0.1) + geom_line(data=d2,aes(x=x,y=y), col="black",size=1)+ geom_pointrange(data=d1, aes(x=x,y=y,ymin=ymin,ymax=ymax), col="darkred", linewidth=1,size=0.5) # 修改图例提取代码,消除内部边距 legend1 = get_legend(ggplot()+ geom_pointrange(data=d1, aes(x=x,y=y,ymin=ymin,ymax=ymax,col=col,fill=col), linewidth=1,size=0.5)+ scale_color_manual(name="",values="darkred")+ scale_fill_manual(name="",values="darkred")+ theme(plot.margin = unit(c(0,0,0,0), "cm"), legend.margin = margin(0,0,0,0), legend.box.margin = margin(0,0,0,0))) legend2 = get_legend(d2 %>% ggplot(aes(x=x,y=y,ymin=ymin,ymax=ymax,fill=col))+ geom_ribbon(alpha=0.2) + geom_line(aes(col=col),size=1)+ scale_color_manual(values="black",name="") + scale_fill_manual(values="black",name="")+ theme(plot.margin = unit(c(0,0,0,0), "cm"), legend.margin = margin(0,0,0,0), legend.box.margin = margin(0,0,0,0))) # 拼接图与图例 cowplot::plot_grid(plot+theme(plot.margin = unit(c(0,0,0,0), "cm")), cowplot::plot_grid(legend1, legend2, ncol=2), rel_heights=c(12,1),ncol=1,nrow=2)
通过设置legend.margin和legend.box.margin为margin(0,0,0,0),可以彻底消除图例上方的空白区域。
内容的提问来源于stack exchange,提问作者Anthony
相关产品推荐
相关产品推荐

