【问题标题】:R sf ggplot labeling multiple polygon that are listed within IDR sf ggplot标记ID中列出的多个多边形
【发布时间】:2019-09-30 16:33:45
【问题描述】:

假设我想绘制和标记多边形(数据框中每行一个多边形),我可以执行以下操作:

library(sf)
library(ggplot2)
nc <- sf::st_read(system.file("shape/nc.shp", package = "sf"), quiet = TRUE)
nc_3857 <- sf::st_transform(nc, 3857)
ggplot(nc_3857[1:3, ]) +
  geom_sf(aes(fill = AREA)) +
  geom_sf_label(aes(label = NAME))

这里NAME 仅指geometry 变量中的一个多边形点列表,可以正常工作。

但是,如果我的 geometry 变量代表每行的多个多边形的列表,我将如何标记它们。我想要一个可以解释不同长度列表的通用版本。例如看这个df:

df <- structure(list(id= structure(1:2, .Label = c("A1", "A2"
), class = "factor"), geometry = structure(list(structure(list(
    list(structure(c(0, 1, 3, 2, 1, 0, 0, 0, 2, 4, 4, 0), .Dim = c(6L, 
    2L)), structure(c(1, 1, 2, 1, 1, 2, 2, 1), .Dim = c(4L, 2L
    ))), list(structure(c(3, 4, 4, 3, 3, 0, 0, 1, 1, 0), .Dim = c(5L, 
    2L)), structure(c(3.3, 3.3, 3.8, 3.8, 3.3, 0.3, 0.8, 0.8, 
    0.3, 0.3), .Dim = c(5L, 2L))), list(structure(c(3, 4, 4, 
    3, 3, 2, 3, 3), .Dim = c(4L, 2L)))), class = c("XY", "MULTIPOLYGON", 
"sfg")), structure(list(list(structure(c(0, 1, 3, 2, 1, 0, 0, 
0, 2, 4, 4, 0), .Dim = c(6L, 2L)), structure(c(1, 1, 2, 1, 1, 
2, 2, 1), .Dim = c(4L, 2L))), list(structure(c(3, 4, 4, 3, 3, 
0, 0, 1, 1, 0), .Dim = c(5L, 2L)), structure(c(3.3, 3.3, 3.8, 
3.8, 3.3, 0.3, 0.8, 0.8, 0.3, 0.3), .Dim = c(5L, 2L)))), class = c("XY", 
"MULTIPOLYGON", "sfg"))), crs = structure(list(epsg = NA_integer_, 
    proj4string = NA_character_), class = "crs"), n_empty = 0L, precision = 0, bbox = structure(c(xmin = 0, 
ymin = 0, xmax = 4, ymax = 4), class = "bbox"), class = c("sfc_MULTIPOLYGON", 
"sfc"))), row.names = c(NA, -2L), class = "data.frame")

对于我的输出,我循环遍历 id 并绘制对应于每个 id 的多边形列表,所以像这样(没有我的循环):

ggplot() + 
  geom_sf(data = df[df$id=="A1",])

我想一般地标记每个多边形列表,因此对于每个图,我都会有“片段 1”、“片段 2”...等。就像在我的第一张图片中一样,取决于有多少片段(在下面的示例中,id= A1 为 3)。

看起来很基本,但无法弄清楚?

【问题讨论】:

    标签: r list ggplot2 sf


    【解决方案1】:

    为了绘图,您需要做的是使用st_cast 将您的MULTIPOLYGON 几何体拆分为多个POLYGON 几何体。默认情况下,这将警告您正在跨几何复制属性(此处为id),在这种情况下这很好,但可能会根据属性导致错误(不要复制面积之类的测量值!)一旦我们有了每行的几何图形,使用geom_sf_label 以相同的方式绘制变得容易。

    library(tidyverse)
    library(sf)
    #> Linking to GEOS 3.6.1, GDAL 2.1.3, PROJ 4.9.3
    df <- structure(list(id = structure(1:2, .Label = c("A1", "A2"), class = "factor"), geometry = structure(list(structure(list(list(structure(c(0, 1, 3, 2, 1, 0, 0, 0, 2, 4, 4, 0), .Dim = c(6L, 2L)), structure(c(1, 1, 2, 1, 1, 2, 2, 1), .Dim = c(4L, 2L))), list(structure(c(3, 4, 4, 3, 3, 0, 0, 1, 1, 0), .Dim = c(5L, 2L)), structure(c(3.3, 3.3, 3.8, 3.8, 3.3, 0.3, 0.8, 0.8, 0.3, 0.3), .Dim = c(5L, 2L))), list(structure(c(3, 4, 4, 3, 3, 2, 3, 3), .Dim = c(4L, 2L)))), class = c("XY", "MULTIPOLYGON", "sfg")), structure(list(list(structure(c(0, 1, 3, 2, 1, 0, 0, 0, 2, 4, 4, 0), .Dim = c(6L, 2L)), structure(c(1, 1, 2, 1, 1, 2, 2, 1), .Dim = c(4L, 2L))), list(structure(c(3, 4, 4, 3, 3, 0, 0, 1, 1, 0), .Dim = c(5L, 2L)), structure(c(3.3, 3.3, 3.8, 3.8, 3.3, 0.3, 0.8, 0.8, 0.3, 0.3), .Dim = c(5L, 2L)))), class = c("XY", "MULTIPOLYGON", "sfg"))), crs = structure(list(epsg = NA_integer_, proj4string = NA_character_), class = "crs"), n_empty = 0L, precision = 0, bbox = structure(c(xmin = 0, ymin = 0, xmax = 4, ymax = 4), class = "bbox"), class = c("sfc_MULTIPOLYGON", "sfc"))), row.names = c(NA, -2L), class = "data.frame")
    df %>%
      st_as_sf %>%
      st_cast("POLYGON", group_or_split = TRUE, warn = FALSE) %>%
      ggplot() +
      geom_sf(aes(fill = id)) +
      geom_sf_label(aes(label = id))
    

    在您的示例中,这看起来有点奇怪,因为A2 多边形与A1 多边形相同,因此颜色和标签被掩盖了。确实有 3 个 A1 标签被绘制,如果你在 ggplot 调用之前添加一行 filter(id == "A1") 可以看到这一点:

    df %>%
      st_as_sf %>%
      st_cast("POLYGON", group_or_split = TRUE, warn = FALSE) %>%
      filter(id == "A1") %>%
      ggplot() +
      geom_sf(aes(fill = id)) +
      geom_sf_label(aes(label = id))
    

    reprex package (v0.2.1) 于 2019-05-13 创建

    【讨论】:

    • 谢谢,你只是漏掉了一行mutate(c = paste("Fragment", seq_along(id), sep=" ")),它改变了geom_sf_label(aes(label = c)),因为我希望以不同的方式命名每件作品,而不是完全相同。您知道如何使用循环引用id 中的每个标签,例如:geom_sf_label(aes(label = df[df$id==i, "c"]))
    • 想通了..geom_sf_label(data = df[df$id==i,], aes(label = c))
    猜你喜欢
    • 2020-12-29
    • 1970-01-01
    • 2019-01-30
    • 2019-11-22
    • 2019-03-10
    • 1970-01-01
    • 2020-11-14
    • 2019-03-02
    • 1970-01-01
    相关资源
    最近更新 更多