使用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
相关产品推荐
相关产品推荐

