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

如何用ggpubr包的ggarrange实现底部图居中并共享图例?

使用ggarrange实现底部图居中+共享公共图例

问题解决步骤

1. 移除所有子图的独立图例

要实现共享图例,首先得把每个子图自带的图例去掉,避免重复显示。在绘图的theme()里添加legend.position = "none"即可。

2. 提取公共图例

从原始绘图对象中提取统一的图例,同时可以调整图例文字大小匹配整体风格。

3. 构建顶部双图行

将前两个图横向并排,保持水平对齐。

4. 构建底部居中单行图

通过添加空白占位符的方式,让单个图在底部行居中显示,宽度和顶部的单个图匹配。

5. 组合所有布局并添加公共图例

把顶部行、底部行组合成上下布局,再将提取的公共图例添加到合适位置。

修改后的完整代码

# 加载包
library(ggplot2)
library(ggpubr)

# 创建子图(移除独立图例)
plt.1 <- ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width, colour = Species)) + 
  geom_point(size = 0.2) +
  theme(
    axis.ticks = element_line(size = 0.2),
    axis.title = element_text(size = 7),
    axis.text = element_text(size = 7),
    panel.grid.major = element_blank(), 
    panel.grid.minor = element_blank(),
    legend.position = "none"  # 移除当前图的图例
  )
plt.2 <- plt.1
plt.3 <- plt.1 

# 提取公共图例(可调整图例文字大小)
common_legend <- get_legend(
  ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width, colour = Species)) + 
    geom_point(size = 0.2) +
    theme(
      legend.title = element_text(size = 7),
      legend.text = element_text(size = 7)
    )
)

# 构建顶部双图行
top_plots <- ggarrange(plt.1, plt.2, ncol = 2, align = "h")

# 构建底部居中单行图(左右添加空白占位符)
bottom_plot <- ggarrange(NULL, plt.3, NULL, 
                         ncol = 3, 
                         widths = c(0.25, 0.5, 0.25))  # 调整宽度比例让中间图居中

# 组合上下布局
combined <- ggarrange(top_plots, bottom_plot, nrow = 2, heights = c(1, 1))

# 添加公共图例到右侧
final_plot <- annotate_figure(combined, right = common_legend)

# 保存图片
ggsave("img.png", plot = final_plot, height = 6, width = 7, dpi = 300, bg = 'white')

关键说明

  • 用legend.position = "none"彻底移除子图图例,解决了原代码中common.legend=TRUE仍显示重复图例的问题。
  • 底部行通过NULL占位符+widths参数控制空白比例,确保目标图居中且宽度匹配顶部单图。
  • 用get_legend()提取图例后,通过annotate_figure()添加到组合图,位置可根据需求调整(如top/bottom等)。

内容的提问来源于stack exchange,提问作者Anderson N. Barbosa

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 22:52:49