【问题标题】:Draw SpatialPolygons with multiple subpolygons and holes using ggplot2使用 ggplot2 绘制具有多个子多边形和孔的 SpatialPolygons
【发布时间】:2017-10-23 18:02:54
【问题描述】:

我想从库sp 中画出SpatialPolygons,并在ggplot2 中有孔。 感谢其他关于 stackoverflow 的问题,我知道在处理顺时针书写的多边形时这是允许的:
http://stackoverflow.com/questions/12047643/geom-polygon-with-multiple-hole/12051278#12051278
实际上,当使用broom::tidy(替换ggplot2::fortify)转换SpatialPolygons 时,孔多边形会按顺时针方向保存以绘制为孔。
在 ggplot2 中,绘制带孔的多边形的方式强制使用fill 绘制一次,然后使用colour 绘制一次,否则您可能会看到线穿过多边形。 在处理多个子多边形时,其中一些带有孔,这更加棘手,broom::tidy 定义的点特征的顺序可能不允许填充多边形(见下图)。
你们中的任何人都有解决这种填充问题行为的方法吗?

这是一个可重现的例子:

library(sp)
library(ggplot2)

# Create two polygons: second would be a hole inside the first
xy = cbind(
  x = c(13.4, 13.4, 13.6, 13.6, 13.4),
  y = c(48.9, 49, 49, 48.9, 48.9)
    )
hole.xy <- cbind(
  x = c(13.5, 13.5, 13.45, 13.45, 13.5),
  y = c(48.98, 48.92, 48.92, 48.98, 48.98)
  )

# Transform as SpatialPolygons with holes
xy.sp <- SpatialPolygons(list(
  Polygons(list(Polygon(xy),
                Polygon(hole.xy, hole = TRUE)), "1"),
  Polygons(list(Polygon(xy + 0.2),
                Polygon(xy + 0.35),
                Polygon(hole.xy + 0.2, hole = TRUE)), "2")
  ))

# Transform SpatialObject to be used by ggplot2
xy.sp.l <- broom::tidy(xy.sp)

ggplot(xy.sp.l) +
  geom_polygon(aes(x = long, y = lat, group = id, fill = id))


(来源:statnmap.com

【问题讨论】:

  • 一种解决方案是在 SpatialPolygons 函数调用中分离多边形。例如id = 2 的两个多边形变为 2a 和 2b。这是一种可能性,还是您正在寻找从 xy.sp.l 开始的解决方案。

标签: r ggplot2 polygon geospatial broom


【解决方案1】:

可能是“重温”sf 包的好时机。在ggplot 中使用sf 对象实际上要容易得多,这要归功于geom_sf 几何:

library("sf")
library("rgeos")
sf_poly <- as(xy.sp, "sf")
sf::st_crs(sf_poly) <- 4326
sf_poly$id <- c(1,2)
ggplot(sf_poly) +
  geom_sf(aes(fill = as.factor(id)))

【讨论】:

  • 确实如此。您的回答以简单的方式解决了这里提出的问题。我想这会鼓励有这个问题的人迁移到 sf... 我个人正在等待sf 足够稳定的参数和函数名称的那一刻。然而,这引发了我的另一个问题,即能够绘制具有 sf 特征的阴影区域多边形。我将不得不修改我的函数以允许使用 sf 进行此操作,然后使用 sf 进行传单。但这是另一个问题,再次...谢谢。
  • 我接受这个答案是为了让人们转移到sf。但是第二个答案被授予,因为这是我的问题的答案。
【解决方案2】:

添加行显示了问题的根源。正在绘制蓝色“多边形”,下 -> 上 -> 孔。

这段代码(不是很优雅,抱歉)使路径回到第一个片段的起点,然后继续进行第三个片段。

 library(dplyr)
    extra <- xy.sp.l %>%
        filter(piece != 1) %>%
        group_by(id, group) %>%
        summarise(last_pt = max(order))


for (n in 1:nrow(extra)) {
    id_ex <- as.character(extra[n,"id"])
    x <- subset(xy.sp.l, id == id_ex & piece == 1 & order == 1)
    x$order <- as.numeric(extra[n,"last_pt"]) + 0.5
    xy.sp.l <- rbind(xy.sp.l,x)
}

xy.sp.l <- xy.sp.l[order(xy.sp.l$id, xy.sp.l$order),] 

【讨论】:

  • 感谢您的回答。回到第一个多边形的一个点似乎可以解决任何新的子多边形或多边形顺序的问题。我想这个技巧可以用于库sp 的任何多边形,以在ggplot2 中绘制。
  • 我相信它会,因为它避免了创建额外多边形(如上面的三角形)的问题。
  • 我奖励这个答案是因为它直接回答了我的问题。但是,为了鼓励人们转移到sf,我接受第一个答案。
【解决方案3】:

这篇文章是一个很好的问题,并且已经收到了很好的答案。我也相信人们应该学习如何使用sf 对象,因为它是 R 中的下一代空间数据类型。但我想分享一下,在这种情况下,ggspatial 包中的geom_spatial 可能是一个选项绘制空间多边形。

library(sp)
library(ggplot2)
library(ggspatial)

ggplot() +
  geom_spatial(xy.sp, aes(fill = id))
# Ignoring argument 'mapping' in geom_spatial.SpatialPolygons
# Autodetect projection: assuming lat/lon (epsg 4326)

【讨论】:

    猜你喜欢
    • 2023-03-30
    • 1970-01-01
    • 2019-07-26
    • 2017-12-08
    • 2016-03-10
    • 2016-10-06
    • 2016-01-19
    • 1970-01-01
    • 2014-04-13
    相关资源
    最近更新 更多