将几个 sf 绑定在一起只绘制第一层

Binding several sf together only plots first layer

我正在尝试创建一个脚本来生成带有测深仪的通用地图,但我正在努力让它发挥作用。 我的问题是,根据我想要制作的地图,我会调用不同的测深层,但是当我将它们绑定在一起时,只会绘制第一个。我不明白问题出在哪里。有什么想法吗?

我创建了一个函数来从 'rnaturalearth' 包中加载我的测深形状文件:

load_shapefile <- function(file, url, shapefile){ 
  if (!file.exists(file.path(tempdir(), file))) {
    url <- url
    download.file(url, file.path(tempdir(), file))
    unzip(file.path(tempdir(), file), exdir = tempdir())
  }
  st_read(dsn = tempdir(), layer = shapefile,
          quiet = TRUE)
}

然后我加载了几个 shapefile:

bathy_200 <- load_shapefile("ne_10m_bathymetry_K_200.zip",
                            "https://www.naturalearthdata.com/http//www.naturalearthdata.com/download/10m/physical/ne_10m_bathymetry_K_200.zip",
                            "ne_10m_bathymetry_K_200")
bathy_1000 <- load_shapefile("ne_10m_bathymetry_J_1000.zip",
                             "https://www.naturalearthdata.com/http//www.naturalearthdata.com/download/10m/physical/ne_10m_bathymetry_J_1000.zip",
                             "ne_10m_bathymetry_J_1000")
bathy_2000 <- load_shapefile("ne_10m_bathymetry_I_2000.zip",
                             "https://www.naturalearthdata.com/http//www.naturalearthdata.com/download/10m/physical/ne_10m_bathymetry_I_2000.zip",
                             "ne_10m_bathymetry_I_2000")

假设我只想绘制 200 和 2000 的等深线,但仍想创建一个通用函数,它也可以让我轻松地绘制 1000 和 2000,或者 200 和 1000:

plot_map <- function(bathy){
ggplot() +
  geom_sf(data = bathy %>%
            left_join(tibble(depth = c(200, 1000, 2000), 
                             fill = c("#E2EFF6", "#B7D7EA", "#8DBEDC")),
                      by = "depth"),
          aes(fill = fill),
          color = NA) +
  coord_sf(xlim = c(-20, 20),
           ylim = c(-20, 20),
           expand = FALSE) +
  scale_fill_identity()
}

当我绘制数据时,仅绘制了 200m shapefile...

plot_map(bind_rows(bathy_200, bathy_2000))

我错过了什么?我尝试了几种解决方案,例如整理数据等,结果还是一样...

我认为你的主要问题是过度绘制,你只能通过设置强填充颜色和 alpha 值才能真正看到:

plot_map <- function(bathy){
ggplot() +
  geom_sf(data = bathy %>%
            left_join(tibble(depth = c(200, 1000, 2000), 
                             fill = c("red", "green", "blue")),
                      by = "depth"),
          aes(fill = fill),
          color = NA, alpha = 0.5) +
  coord_sf(xlim = c(-20, 20),
           ylim = c(-20, 20),
           expand = FALSE) +
  scale_fill_identity()
}

plot_map(bind_rows(bathy_200, bathy_2000))

如果您可以在单独的图层中绘制每个数据框,这个问题就会消失。为了在不必指定首先绘制哪个图层的情况下控制它,我将编写如下函数:

plot_map <- function(...){
  
  dfs <- list(...)
  
  dfs <- dfs[order(sapply(dfs, function(x) mean(x$depth)))]
  
  cols <- c("200" = "#E2EFF6", "1000" = "#B7D7EA", "2000" = "#8DBEDC")
  
  ggplot() +
    lapply(dfs, function(df) {
      geom_sf(data = df, aes(fill = factor(depth)), color = NA)
    }) +
    coord_sf(xlim = c(-20, 20),
             ylim = c(-20, 20),
             expand = FALSE) +
    scale_fill_manual(values = cols) +
    theme_bw() +
    labs(fill = 'depth') +
    theme(panel.background = element_rect(fill = '#A0A978'),
          panel.grid = element_line(colour =  '#C0C0C080'))
}

这允许您单独传入数据帧而不是绑定它们。最浅的层总是先绘制,较深的层在最上面

plot_map(bathy_200, bathy_1000, bathy_2000)