# 如何使用geom_sf绘制具有坐标多个孔的多边形？

##### 问题描述投票：1回答：2

st_cast states的文档：

id整数向量，表示应如何对几何进行分组（默认值：无分组）

``````library(tidyverse)
library(transformr)
library(ggpolypath)
library(sf)

get_letter <- function(){

# Extract coordinates from Picture object
x <- letter_xml@paths\$text@letters[1]\$path@x
y <- letter_xml@paths\$text@letters[1]\$path@y

one_letter <- tibble(
x,
y,
x.n = names(x),
id = 1
)

one_letter <- one_letter %>%
mutate(is.move = x.n == "move") %>%
mutate(section = cumsum(is.move)) %>%

group_by(section) %>%
mutate(section.length = n()) %>%
ungroup() %>%
filter(section.length >= 3)

one_letter <- select(one_letter, x, y, id, section)
}

letter_to_sf <- function(one_letter){
one_letter_sf <- one_letter %>%
st_as_sf(coords = c("x", "y")) %>%
summarise(geometry = st_combine(geometry)) %>%
st_cast(to = "POLYGON") %>%
st_normalize()

df2 <- data.frame(
id = 1,
one_letter_sf\$geometry
)
}
one_letter <- get_letter()
one_letter_sf <- letter_to_sf(one_letter)

# Incorrect using xy df
ggplot(one_letter) +
geom_polygon(aes( x = x, y = y))

# Correct using xy df
ggplot(one_letter) +
geom_polypath(aes(x = x, y = y, group = section))

# Incorrect using sf
ggplot(one_letter_sf) +
geom_sf(aes(geometry = geometry))
``````
r ggplot2 sf
##### 2个回答
2

``````library(tidyverse)
library(sf)
#> Linking to GEOS 3.7.1, GDAL 2.4.0, PROJ 5.2.0

one_letter <- tibble::tibble(
x = c(317.422, 315.605, 310.16, 304.367, 300.527, 299.141, 299.141, 299.141, 299.797, 301.297, 301.719, 300.805, 298.199, 295.684, 294.172, 293.672, 293.672, 293.672, 294.172, 295.684, 298.199, 300.805, 301.719, 300.684, 297.75, 294.93, 293.246, 292.688, 292.688, 292.688, 294.367, 299.203, 306.891, 314.566, 317.125, 319.695, 327.41, 335.234, 340.207, 341.953, 341.953, 341.953, 340.152, 334.797, 325.941, 316.715, 313.641, 312.145, 307.656, 303.695, 301.5, 300.828, 300.828, 300.828, 301.121, 301.906, 303.047, 304.066, 304.406, 305.078, 306.82, 307.094, 308.059, 312.82, 317.008, 318.406, 320.199, 325.586, 331.316, 335.109, 336.484, 336.484, 336.484, 336.016, 334.609, 332.25, 329.828, 328.938, 328.953, 329.332, 330.355, 332.008, 333.723, 334.297, 334.863, 336.563, 338.102, 338.375, 338.004, 336.723, 336.188, 336.188, 336.188, 336.516, 337.395, 338.664, 339.793, 340.172, 340.664, 342.148, 343.793, 344.91, 345.328, 345.328, 345.328, 344.5, 342.234, 338.832, 335.664, 334.609, 333.41, 329.813, 326.332, 324.152, 323.328, 323.281, 322.734, 318.75, 317.422, 317.422, 317.719, 318.82, 322.137, 325.664, 327.996, 328.844, 328.844, 328.844, 328.023, 325.723, 322.172, 318.75, 317.609, 316.52, 313.258, 309.871, 307.672, 306.891, 306.891, 306.891, 307.727, 310.031, 313.469, 316.656, 317.719, 317.719, 317.813, 319.559, 324.809, 330.023, 333.281, 334.406, 334.406, 334.406, 333.215, 329.797, 324.387, 319.008, 317.219, 315.516, 310.41, 305.215, 301.898, 300.734, 300.734, 300.734, 301.906, 305.289, 310.66, 316.023, 317.813, 317.813),
y = c(8101.36, 8101.36, 8100.18, 8096.9, 8091.93, 8087.22, 8085.66, 8084.56, 8081.29, 8078.09, 8077.52, 8077.23, 8075.97, 8073.87, 8071.21, 8068.79, 8067.98, 8067.23, 8064.98, 8062.39, 8060.21, 8058.79, 8058.44, 8058.05, 8056.45, 8053.89, 8050.75, 8047.95, 8047.02, 8045.46, 8040.79, 8036.11, 8033.15, 8032.13, 8032.13, 8032.13, 8033.22, 8036.35, 8041.29, 8046.18, 8047.81, 8049.44, 8054.32, 8059.05, 8061.93, 8062.91, 8062.91, 8062.91, 8063.15, 8063.99, 8065.55, 8067.38, 8067.98, 8068.39, 8069.6, 8070.93, 8071.82, 8072.16, 8072.16, 8072.16, 8071.58, 8071.45, 8071.03, 8069.53, 8068.88, 8068.88, 8068.88, 8070.09, 8073.45, 8078.52, 8083.29, 8084.88, 8085.88, 8088.91, 8092.53, 8095.71, 8097.88, 8098.47, 8099.19, 8101.34, 8103.39, 8104.62, 8105.03, 8105.03, 8105.03, 8104.52, 8103.37, 8103.05, 8102.77, 8101.41, 8100.18, 8099.77, 8099.41, 8098.35, 8097.18, 8096.39, 8096.09, 8096.09, 8096.09, 8096.54, 8097.78, 8099.61, 8101.3, 8101.86, 8102.7, 8105.23, 8107.9, 8109.66, 8110.3, 8110.3, 8110.3, 8109.68, 8107.85, 8104.8, 8101.63, 8100.56, 8100.69, 8101.36, 8101.36, 8101.36, 8094.8, 8094.8, 8094.05, 8092, 8088.89, 8085.95, 8084.97, 8084.01, 8081.13, 8078.12, 8076.14, 8075.44, 8075.44, 8075.44, 8076.13, 8078.1, 8081.17, 8084.17, 8085.17, 8086.12, 8088.97, 8092.03, 8094.06, 8094.8, 8094.8, 8094.8, 8056.27, 8056.27, 8055.66, 8053.93, 8051.15, 8048.35, 8047.42, 8046.52, 8043.83, 8041.07, 8039.3, 8038.67, 8038.67, 8038.67, 8039.27, 8041, 8043.75, 8046.5, 8047.42, 8048.34, 8051.1, 8053.89, 8055.65, 8056.27, 8056.27, 8056.27),
id = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
section = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L)
)

one_letter %>%
group_by(section) %>%
group_split() %>%
map(~ select(.x, x, y) %>% as.matrix) %>%
st_polygon() %>%
st_sfc() %>%
st_sf() %>%
ggplot() +
geom_sf()
``````

reprex package创建于2019-03-04（v0.2.1）

0

``````library(tidyverse)
library(sf)
#> Linking to GEOS 3.7.1, GDAL 2.4.0, PROJ 5.2.0

one_letter <- tibble::tibble(
x = c(317.422, 315.605, 310.16, 304.367, 300.527, 299.141, 299.141, 299.141, 299.797, 301.297, 301.719, 300.805, 298.199, 295.684, 294.172, 293.672, 293.672, 293.672, 294.172, 295.684, 298.199, 300.805, 301.719, 300.684, 297.75, 294.93, 293.246, 292.688, 292.688, 292.688, 294.367, 299.203, 306.891, 314.566, 317.125, 319.695, 327.41, 335.234, 340.207, 341.953, 341.953, 341.953, 340.152, 334.797, 325.941, 316.715, 313.641, 312.145, 307.656, 303.695, 301.5, 300.828, 300.828, 300.828, 301.121, 301.906, 303.047, 304.066, 304.406, 305.078, 306.82, 307.094, 308.059, 312.82, 317.008, 318.406, 320.199, 325.586, 331.316, 335.109, 336.484, 336.484, 336.484, 336.016, 334.609, 332.25, 329.828, 328.938, 328.953, 329.332, 330.355, 332.008, 333.723, 334.297, 334.863, 336.563, 338.102, 338.375, 338.004, 336.723, 336.188, 336.188, 336.188, 336.516, 337.395, 338.664, 339.793, 340.172, 340.664, 342.148, 343.793, 344.91, 345.328, 345.328, 345.328, 344.5, 342.234, 338.832, 335.664, 334.609, 333.41, 329.813, 326.332, 324.152, 323.328, 323.281, 322.734, 318.75, 317.422, 317.422, 317.719, 318.82, 322.137, 325.664, 327.996, 328.844, 328.844, 328.844, 328.023, 325.723, 322.172, 318.75, 317.609, 316.52, 313.258, 309.871, 307.672, 306.891, 306.891, 306.891, 307.727, 310.031, 313.469, 316.656, 317.719, 317.719, 317.813, 319.559, 324.809, 330.023, 333.281, 334.406, 334.406, 334.406, 333.215, 329.797, 324.387, 319.008, 317.219, 315.516, 310.41, 305.215, 301.898, 300.734, 300.734, 300.734, 301.906, 305.289, 310.66, 316.023, 317.813, 317.813),
y = c(8101.36, 8101.36, 8100.18, 8096.9, 8091.93, 8087.22, 8085.66, 8084.56, 8081.29, 8078.09, 8077.52, 8077.23, 8075.97, 8073.87, 8071.21, 8068.79, 8067.98, 8067.23, 8064.98, 8062.39, 8060.21, 8058.79, 8058.44, 8058.05, 8056.45, 8053.89, 8050.75, 8047.95, 8047.02, 8045.46, 8040.79, 8036.11, 8033.15, 8032.13, 8032.13, 8032.13, 8033.22, 8036.35, 8041.29, 8046.18, 8047.81, 8049.44, 8054.32, 8059.05, 8061.93, 8062.91, 8062.91, 8062.91, 8063.15, 8063.99, 8065.55, 8067.38, 8067.98, 8068.39, 8069.6, 8070.93, 8071.82, 8072.16, 8072.16, 8072.16, 8071.58, 8071.45, 8071.03, 8069.53, 8068.88, 8068.88, 8068.88, 8070.09, 8073.45, 8078.52, 8083.29, 8084.88, 8085.88, 8088.91, 8092.53, 8095.71, 8097.88, 8098.47, 8099.19, 8101.34, 8103.39, 8104.62, 8105.03, 8105.03, 8105.03, 8104.52, 8103.37, 8103.05, 8102.77, 8101.41, 8100.18, 8099.77, 8099.41, 8098.35, 8097.18, 8096.39, 8096.09, 8096.09, 8096.09, 8096.54, 8097.78, 8099.61, 8101.3, 8101.86, 8102.7, 8105.23, 8107.9, 8109.66, 8110.3, 8110.3, 8110.3, 8109.68, 8107.85, 8104.8, 8101.63, 8100.56, 8100.69, 8101.36, 8101.36, 8101.36, 8094.8, 8094.8, 8094.05, 8092, 8088.89, 8085.95, 8084.97, 8084.01, 8081.13, 8078.12, 8076.14, 8075.44, 8075.44, 8075.44, 8076.13, 8078.1, 8081.17, 8084.17, 8085.17, 8086.12, 8088.97, 8092.03, 8094.06, 8094.8, 8094.8, 8094.8, 8056.27, 8056.27, 8055.66, 8053.93, 8051.15, 8048.35, 8047.42, 8046.52, 8043.83, 8041.07, 8039.3, 8038.67, 8038.67, 8038.67, 8039.27, 8041, 8043.75, 8046.5, 8047.42, 8048.34, 8051.1, 8053.89, 8055.65, 8056.27, 8056.27, 8056.27),
id = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
section = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L)
)

one_letter %>%
st_as_sf(coords = c("x", "y")) %>%
group_by(section) %>%
summarise(do_union = FALSE) %>%
st_cast("POLYGON") %>%
mutate(hole = section > 1) %>%
group_by(hole) %>%
summarise(do_union = FALSE) %>%
st_intersection() %>%
filter(origins == "1") %>%
ggplot() +
geom_sf()
``````

reprex package创建于2019-03-04（v0.2.1）