You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 16:28:10