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

Rod*_*_BC 3 google-maps r facet 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)
Run Code Online (Sandbox Code Playgroud)

ggplot 地图

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

TM 地图

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

Z.L*_*Lin 6

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

这里有两个问题:

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

  2. 无论如何,明确的设置lims()违背了自由缩放的目的。

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

CoordSf2 <- ggproto("CoordSf2",
                    CoordSf,
                    is_free = function() TRUE)
trace(coord_sf, edit = TRUE)
Run Code Online (Sandbox Code Playgroud)

运行该trace(...)行将出现一个弹出窗口,其中包含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
Run Code Online (Sandbox Code Playgroud)

mapa现在使用落在所需限制内的多边形子集进行绘制,并将小面比例设置为“自由”并coord_sf指向允许它的修改版本:

ggplot() +
  layer_spatial(mapa[keep, ]) +
  facet_wrap(~grupo, scales = "free")
Run Code Online (Sandbox Code Playgroud)

结果

但就个人而言?我可能只是制作单独的图并将它们缝合在一起,就像这个问题cowplot中演示的方法一样。