在R中,生成类似于这个Voronoi图的填充Delaunay图。

4

鸢尾花数据集为例,

我正在尝试创建Voronoi和Delaunay分区的绘图。

使用ggplot和ggforce包,我可以很好地完成Voronoi图的绘制。

#voronoi plot with filled polygons
ggplot(iris, aes(Sepal.Length, Sepal.Width)) +
  geom_voronoi_tile(aes(fill = Petal.Length))

在此输入图像描述 现在我想用 Delaunay 三角剖分做一个类似的图,其中三角形也像上面 Voronoi 图中的多边形一样填充,但是,我无法弄清楚如何通过第三个变量来填充/着色三角形

# Delaunay triangles
ggplot(iris, aes(Sepal.Length, Sepal.Width)) +
  geom_delaunay_tile(aes(fill = Petal.Length))

enter image description here


FYI https://github.com/thomasp85/ggforce/issues/293 - tjebo
@tjebo 是的,我也看到了。但是我已经寻找了其他绘制方法,而不是依赖于ggforce,但是还没有找到一个有效的替代方案。 - Myriad
@tjebo 谢谢,我之前也在 ggforce 的 GitHub 页面上提交了一个与此相关的问题,但是没有得到回答 https://github.com/thomasp85/ggforce/issues/292 - Myriad
2
我猜Thomas会忙于其他事情。我相信这个问题肯定有一个相当简单的解决方法,因为我感觉这与Stat和Geom中设置的必需/默认美学有关。这些东西经常让我头痛不已,我通常希望像AllanCameron或Teunbrand这样的巫师能够告诉我问题出在哪里。 - tjebo
1
@tjebo 你太客气了。实际上,我下面勾画的方法应该很容易集成到ggforce中。 - Allan Cameron
显示剩余3条评论
1个回答

4
在沃罗诺伊图中,点和图块之间存在一一对应关系,因此可以轻松地将填充美学映射到图块上。您数据框中的每一行都将有自己的图块,因此可以指定填充、透明度等。
但是,在德劳内三角剖分中情况并非如此,您数据框中的每一行描述一个单独的顶点,因此每个图块需要3行数据来描述。这3行具有不同的花瓣长度值,并且行与图块之间没有一一对应关系。
显然的选择是对三个顶点的花瓣长度取平均值,但似乎ggforce没有以这种方式插值顶点的选项。但是,我们可以使用deldir包以与ggforce相同的方式来实现这一点:
library(ggplot2)
library(deldir)

tri <- triang.list(deldir(iris$Sepal.Length, iris$Sepal.Width))
do.call(rbind, lapply(seq_along(tri), 
                      function(x) {
  data.frame(Sepal.Length = tri[[x]]$x, Sepal.Width = tri[[x]]$y, 
             Petal.Length = mean(iris$Petal.Length[tri[[x]]$ptNum]),
             tri = x)
  })) |>
  ggplot(aes(Sepal.Length, Sepal.Width)) +
  geom_polygon(aes(fill = Petal.Length, group = tri)) 

enter image description here


额外的

为了进行渐变填充三角形,最好在2D插值上绘制空白三角形:

library(interp)
library(ggforce)

interp(iris$Sepal.Length, iris$Sepal.Width, iris$Petal.Length, 
              duplicate = "mean", nx = 1000, ny = 1000) |>
  interp2xyz() |>
  as.data.frame() |>
  setNames(names(iris)[1:3]) |>
  ggplot(aes(Sepal.Length, Sepal.Width)) +
  geom_raster(aes(fill = Petal.Length)) +
  scale_fill_continuous(na.value = NA) +
  geom_delaunay_tile(data = iris, fill = NA, color = "#00000050")

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接