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

使用ggarrange()与geom_sf()时保持地图宽高比且统一宽度

固定宽度且保持宽高比的多面板地图解决方案

要实现各面板宽度一致(如8cm)同时不扭曲地图比例,核心是根据每个区域的坐标范围计算相对高度,再通过ggarrange的heights参数精准控制面板高度。以下是可行的复现代码和步骤:

步骤1:计算每个面板的相对高度

每个地图的宽高比由其x、y轴范围决定。固定宽度时,面板高度需与y轴范围/x轴范围成正比(因为宽高比= x范围/y范围,高度= 宽度/宽高比)。

步骤2:生成并组合面板

先定义各区域的坐标范围,批量生成地图,再用计算好的相对高度组合面板:

library(rnaturalearth)
library(tidyverse)
library(ggpubr)

# 定义三个滨海区域的坐标范围
regions <- list(
  list(xlim = c(-6, 3), ylim = c(48.5, 52)),
  list(xlim = c(-10, -1), ylim = c(43, 48.5)),
  list(xlim = c(3, 10), ylim = c(41, 44))
)

# 计算固定宽度下的相对高度
calc_rel_height <- function(xlim, ylim) {
  x_range <- diff(xlim)
  y_range <- diff(ylim)
  y_range / x_range  # 高度与该值成正比
}

rel_heights <- map_dbl(regions, ~calc_rel_height(.x$xlim, .x$ylim))

# 批量生成地图(关闭coord_sf的自动扩展,避免比例偏差)
plots <- map(regions, function(region) {
  ggplot() +
    geom_sf(data = ne_countries(scale = "small", returnclass = "sf")) +
    coord_sf(xlim = region$xlim, ylim = region$ylim, expand = FALSE) +
    theme_minimal() +
    theme(plot.margin = margin(5, 5, 5, 5))  # 统一面板边距
})

# 组合面板,设置相对高度
ggarrange(plotlist = plots, ncol = 1, heights = rel_heights)

步骤3:导出固定宽度的图

用ggsave指定宽度为8cm,导出时会自动匹配计算好的高度:

ggsave("french_coastal_regions.png", width = 8, units = "cm", dpi = 300)

替代方案:使用patchwork包(更简洁)

patchwork对多面板比例的控制更直观,同样可以实现需求:

library(patchwork)

# 按垂直方向组合地图,设置总宽度为8cm,高度用相对比例
plots[[1]] / plots[[2]] / plots[[3]] +
  plot_layout(widths = unit(8, "cm"), heights = rel(rel_heights))

为什么之前的方法失效?

  • align = "h"会强制所有面板高度一致,直接破坏地图的宽高比;
  • 手动提取比例失败通常是因为未关闭coord_sf的expand = TRUE(默认会扩展坐标范围,导致实际比例与计算值不符),或未统一面板边距。

内容的提问来源于stack exchange,提问作者Fred-LM

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 17:22:51