R sf ggplot маркировка нескольких полигонов, перечисленных в ID - PullRequest
2 голосов
/ 13 мая 2019

Допустим, я хочу построить и обозначить полигоны (по одному многоугольнику на строку в кадре данных), я могу сделать следующее:

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))

enter image description here Здесь 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» ... и т. Д.как на моем первом изображении в зависимости от того, сколько фрагментов (3 в примере ниже для id = A1).enter image description here

Кажется довольно простым, но не можете понять это?

1 Ответ

2 голосов
/ 14 мая 2019

Что вам нужно сделать для построения графика, так это использовать 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 меток, вы можете увидеть это, добавив линию filter(id == "A1") перед ggplot вызовом:

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))

Создано в 2019-05-13 пакетом Представления (v0.2.1)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...