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

如何绘制含三个同尺寸ggplot2子图且仅显示单个图例的面板?

解决方法

有两种简洁的方式可以实现单图例+子图同尺寸的需求:

方法一:使用patchwork包(推荐)

patchwork是专门用于ggplot2图形组合的工具,自带图例收集功能,代码更简洁直观:

首先安装并加载patchwork:

install.packages("patchwork")
library(patchwork)

保留你原来的子图代码,直接组合并收集图例:

library(terra)
library(ggplot2)
library(tidyterra)
v <- vect(system.file("ex/lux.shp", package = "terra"))

p1 <- ggplot(v) +
  geom_spatvector(aes(fill = NAME_2), color = "grey") +
  borders() +
  coord_sf(xlim = c(4, 8), ylim = c(49, 49.5))

p2 <- ggplot(v) +
  geom_spatvector(aes(fill = NAME_2), color = "grey") +
  borders() +
  coord_sf(xlim = c(4, 8), ylim = c(49.5, 50))

p3 <- ggplot(v) +
  geom_spatvector(aes(fill = NAME_2), color = "grey") +
  borders() +
  coord_sf(xlim = c(4, 8), ylim = c(50, 50.5))

# 垂直堆叠子图并合并图例
p1 / p2 / p3 + 
  plot_layout(guides = "collect")

p1 / p2 / p3表示将三个图垂直排列,guides = "collect"会自动把重复的图例合并为一个,子图会自动调整为相同尺寸。你还可以通过plot_annotation()添加整体标题等元素。

方法二:使用gridExtra包(适配原grid.arrange方案)

如果坚持使用grid.arrange,需要先移除子图的图例,再单独提取图例进行组合:

  1. 修改子图,去掉各自的图例:
p1_noleg <- p1 + theme(legend.position = "none")
p2_noleg <- p2 + theme(legend.position = "none")
p3_noleg <- p3 + theme(legend.position = "none")
  1. 从任意一个原始子图中提取单个图例:
# 定义提取图例的辅助函数
get_legend <- function(myggplot){
  tmp <- ggplot_gtable(ggplot_build(myggplot))
  leg_index <- which(sapply(tmp$grobs, function(x) x$name) == "guide-box")
  legend <- tmp$grobs[[leg_index]]
  return(legend)
}

single_legend <- get_legend(p1)
  1. 组合无图例的子图和单独的图例:
library(gridExtra)
grid.arrange(
  arrangeGrob(p1_noleg, p2_noleg, p3_noleg, ncol = 1),
  single_legend,
  ncol = 2,
  widths = c(4, 1) # 调整主图区域与图例的宽度比例,确保子图尺寸一致
)

内容的提问来源于stack exchange,提问作者Tpellirn

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 07:32:35