R:使用 ggplot2 对地图进行分面

R: Facet a map with ggplot2

我正在尝试使用 ggplot2 对地图进行分面,因为它比 tmap 包更快。可惜得到的地图不是我心目中的样子。

library(ggplot2)
library(raster)
library(ggspatial)


chile  <- getData("GADM",country="Chile",level=1)

chile2= chile[c(2,4:5,7,8,12:16),]
chile2$grupo=1
chile3= chile[c(1,3,6,9:11),]
chile3$grupo=2
mapa=rbind(chile2, chile3)

ggplot() +
  layer_spatial(mapa) +
  lims(x = c( -77.1,-65), y = c(-57, -15))+
  facet_wrap(~grupo)

遗憾的是上面的地图不是我需要的。使用 tmap,我得到了下面的地图,这是我真正需要的地图:

你知道如何使用 ggplot2 解决这个问题吗?

这是可以做到的,但我不确定是否真的值得付出努力。

这里有两个问题:

  1. 通常,您可以通过设置scales = "free"facet_wrap的每个方面获得不同的比例(在本例中为纬度/经度),但layer_spatial仅有效使用 coord_sf 坐标系,并且 coord_sf 被硬编码为仅适用于固定比例(在 ggplot GH 页面上有一个 discussion 涵盖了这是如何发生的);

  2. 设置 lims() 显然违背了自由比例的目的。

对于第一个问题,我们可以违背软件包开发人员的意图来定义接受自由尺度的坐标系的替代版本。 (我并不是说 应该 完成,但 可以 完成。买者自慎。)

CoordSf2 <- ggproto("CoordSf2",
                    CoordSf,
                    is_free = function() TRUE)
trace(coord_sf, edit = TRUE)

运行 trace(...) 行将导致弹出窗口 window,其中包含 coord_sf 的代码。将最后一段从 ggproto(NULL, CoordSf, ...) 修改为 ggproto(NULL, CoordSf2, ...) 会将 coord_sf 指向我们修改后的 CoordSf2 而不是原来的 CoordSf。此效果将一直保持到当前 R 会话结束,或者您可以通过 运行 untrace(coord_sf).

提前终止它

对于第二个问题,我想限制被设置为只显示限制内的多边形。我们可以在数据框中执行此过滤步骤,然后再将其传递给 ggplot:

library(dplyr)

keep <- lapply(mapa@polygons, bbox) %>%                    # retrieve bounding box for each polygon
  lapply(function(x) c(x) <= c(-77.1, -57, -65, -15)) %>%  # compare each polygon's bbox against
  lapply(function(x) x == c(F, F, T, T)) %>%               # desired limits, if within, 
  sapply(all)                                              # results should be FFTT

keep # only the 10th polygon is outside the limits
 [1]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE
[11]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE

现在用 mapa 多边形的子集绘制在所需范围内,小平面比例设置为“自由”并且 coord_sf 指向允许它的修改版本:

ggplot() +
  layer_spatial(mapa[keep, ]) +
  facet_wrap(~grupo, scales = "free")

不过就个人而言?我可能只是制作单独的图并将它们拼接在一起,就像 .

中演示的 cowplot 方法