如何使用ggplot(geom_sf)实现两张空间地图并排等高排列
解决方案
问题核心原因
coord_sf()默认会严格保持地图的地理正确纵横比,不同经纬度范围的地图自身宽高比不同,直接用grid.arrange按等宽排列时,自然会出现高度不匹配的问题。
推荐方案:用patchwork包+比例宽度排版
patchwork是专门用于ggplot多图排版的包,配合预计算的两个地图宽度比例,可实现高度完全匹配,同时保留地图的正确地理比例不被拉伸。
完整修改后代码
library(ggplot2) library(rnaturalearth) library(patchwork) # 替换gridExtra,排版更智能 ### 加载地图数据 world <- ne_countries(scale = "medium", returnclass = "sf") ### 绘制欧洲地图 Europe <- ggplot(data = world) + geom_sf(fill="grey70",color="grey90",size=0.3) + coord_sf(xlim = c(-12, 33), ylim = c(40, 65), expand = F, datum = NA)+ theme_minimal()+ theme(axis.title=element_blank(), plot.background = element_rect(colour = "grey50", fill=NA), plot.margin = unit(c(0, 0, 0, 0), "null")) ### 绘制北美地图 NorthAmerica <- ggplot(data = world) + geom_sf(fill="grey70",color="grey90",size=0.3) + coord_sf(xlim = c(-127, -52), ylim = c(15, 65), expand = F, datum = NA)+ theme_minimal()+ theme(axis.title=element_blank(), plot.background = element_rect(colour = "grey50", fill=NA), plot.margin = unit(c(0, 0, 0, 0), "null")) # 计算两个地图的正确宽度比例(保留地理纵横比) ## 北美参数 na_y_span <- 65 - 15 na_x_span <- (-52) - (-127) na_avg_lat <- (15 + 65)/2 * pi/180 na_aspect <- (na_x_span * cos(na_avg_lat)) / na_y_span ## 欧洲参数 eu_y_span <- 65 - 40 eu_x_span <- 33 - (-12) eu_avg_lat <- (40 + 65)/2 * pi/180 eu_aspect <- (eu_x_span * cos(eu_avg_lat)) / eu_y_span # 按比例宽度并排排列,高度自动完全匹配 NorthAmerica + Europe + plot_layout(nrow = 1, widths = c(na_aspect, eu_aspect))
替代方案:强制固定纵横比(适合非严格地理场景)
如果你可以接受地图轻微拉伸来对齐,不需要保留严格地理比例,可直接在coord_sf中添加aspect = 1参数,强制两个地图宽高比一致,之后再用任意排版工具排列即可。
如果你一定要用gridExtra
可以将上面计算得到的宽高比传入grid.arrange的widths参数:
library(gridExtra) grid.arrange(NorthAmerica, Europe, nrow = 1, widths = c(na_aspect, eu_aspect))
内容的提问来源于stack exchange,提问作者Johannes
相关产品推荐
相关产品推荐

