【问题标题】:How to merge polygon outlines?如何合并多边形轮廓?
【发布时间】:2015-11-19 17:28:08
【问题描述】:

我有两个多边形,我想在ggplot2 中合并它们的轮廓。我怎么做?

目前我设法在视觉上合并多边形,但我的解决方案不适用于轮廓:

tmp <- structure(list(y.min = c(68, 72), y.max = c(72, 73), x.min = c(-160, 
-130), x.max = c(-120, -120), ID = structure(1:2, .Label = c("a", 
"b"), class = "factor")), .Names = c("y.min", "y.max", "x.min", 
"x.max", "ID"), row.names = 1:2, class = "data.frame")

## Object tmp contains limits for the polygons I want to merge

## Transform them ready for ggplot2:

pols <- lapply(1:nrow(tmp), function(i){
  data.frame(ID = tmp$ID[i], y = c(tmp$y.max[i], tmp$y.max[i], tmp$y.min[i],
tmp$y.min[i]), x = c(tmp$x.min[i], tmp$x.max[i], tmp$x.max[i], tmp$x.min[i]))
})
pols <- do.call(rbind, pols)

## I can use the ID as a group argument to plot the polygons. 
## I get rid of the outlines by using NA as color:

library(ggplot2)

ggplot(data = pols, aes(x = x, y = y)) + geom_point() +
geom_polygon(aes(group = ID), alpha = 0.3, color = NA)

## I however would like to merge these polygons and only plot the outlines without filling: 

ggplot(data = pols, aes(x = x, y = y)) + geom_point() + 
geom_polygon(aes(group = ID), alpha = 0, color = "black") + 
annotate("segment", x = -130, y = 71, xend = -125, yend = 71.8,
arrow = arrow(length = unit(0.5, "cm"))) + 
annotate("text", x = -130, y = 70.8, label = "I want to get rid of this line")

【问题讨论】:

  • 这是一个空间数据问题 - ggplot 并不真正相关。我认为rgdalspatstat 软件包可能会有所帮助。至少有强烈相关(如果不重复)的问题such as thisand this,唯一真正的区别是您的源数据不是地理数据。
  • @Gregor:如果可能的话,我想找到一种不加载额外包的方法。我知道这个问题可以使用空间包来解决,但是对于这样一个小问题,这些感觉就像是重型武器。必须将数据转换为空间对象并返回到data.frame。 R 基础中有chull 函数,但它只计算凸包,而不是示例中的多边形。必须有一种数学方法来定义这些多边形的轮廓。我想不出一个,这就是我问的原因。
  • 一种解决方案是顺时针对图中的点进行排序并使用geom_path,但是我如何告诉 R 顺时针对点进行排序?
  • 嗯,这又是空间包已经处理的事情了。如果您决心重新发明轮子,我同意顺时针排序点将是一个好的开始。如果您不想加载其他包,我建议您在自己重新实现之前查看他们的代码以了解他们如何解决问题。
  • 这也取决于你的代码需要多通用。您可能能够找到并采取捷径,所有组成多边形都是凸的,并且如果它们的区域不重叠 - 只有它们的边缘。对于凸多边形的顺时针排序,在内部选择一个点并计算每个边界点与穿过内部点的垂直或水平线所成的角度,然后按角度排序。这不适用于非凸多边形。

标签: r ggplot2 polygon spatial


【解决方案1】:

这是一种方法。正如@Gregor 在 cmets 中指出的那样,使用空间包最容易做到这一点。我用spatstat

library(spatstat)

polys <- lapply(1:nrow(tmp), function(i) {
  owin(c(tmp$x.min[i], tmp$x.max[i]), c(tmp$y.min[i], tmp$y.max[i]))
})

merged.poly <- union.owin(polys[[1]], polys[[2]])
merged.poly <- data.frame(x = merged.poly$bdry[[1]]$x, y = merged.poly$bdry[[1]]$y)

ggplot() + geom_polygon(data = merged.poly, aes(x = x, y = y),
color = "black", alpha = 0) + geom_point(data = pols, aes(x = x, y = y))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-03
    • 2014-11-24
    • 2022-07-12
    • 2016-04-30
    • 1970-01-01
    • 2013-10-25
    相关资源
    最近更新 更多