R sf ggplot 标记 ID 中列出的多个多边形
R sf ggplot labeling multiple polygon that are listed within ID
假设我想绘制和标记多边形(数据框中每行一个多边形),我可以执行以下操作:
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",])
我想一般性地标记每个多边形列表,因此对于每个图我会有 "Fragment 1"、"Fragment 2"...等。就像在我的第一张图片中一样,这取决于有多少片段(下面示例中的 3 个,对于 id = A1)。
看起来很基础但无法理解?
为了绘图,您需要做的是使用 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 创建
假设我想绘制和标记多边形(数据框中每行一个多边形),我可以执行以下操作:
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",])
我想一般性地标记每个多边形列表,因此对于每个图我会有 "Fragment 1"、"Fragment 2"...等。就像在我的第一张图片中一样,这取决于有多少片段(下面示例中的 3 个,对于 id = A1)。
看起来很基础但无法理解?
为了绘图,您需要做的是使用 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 创建