3D散点图中的凸形船体

时间:2016-12-14 15:12:48

标签: r 3d convex-hull qhull

我使用“rgl”here

包来关注3D可视化教程

所以我能够用“虹膜”数据绘制一个3D散点图并创建一个围绕95%数据点的椭球:

library("rgl")
data(iris)
x <- sep.l <- iris$Sepal.Length
y <- pet.l <- iris$Petal.Length
z <- sep.w <- iris$Sepal.Width
plot3d(x, y, z, col="blue", box = FALSE,
   type ="s", radius = 0.15)
ellips <- ellipse3d(cov(cbind(x,y,z)), 
                centre=c(mean(x), mean(y), mean(z)), level = 0.95)
plot3d(ellips, col = "blue", alpha = 0.2, add = TRUE, box = FALSE)

我知道前50个数据点与数据集的其余部分相比属于不同的人口,因此以不同的方式对它们进行着色,并使用两个椭球来覆盖它们:

plot3d(x, y, z, col=c(rep("gold2",50),rep("forestgreen",100)), box = FALSE,
   type ="s", radius = 0.15)
ellips1 <- ellipse3d(cov(cbind(x[1:50],y[1:50],z[1:50])), 
                centre=c(mean(x[1:50]), mean(y[1:50]), mean(z[1:50])), level = 0.999)
ellips2 <- ellipse3d(cov(cbind(x[51:150],y[51:150],z[51:150])), 
                 centre=c(mean(x[51:150]), mean(y[51:150]), mean(z[51:150])), level = 0.999)
plot3d(ellips1, col = "gold2", alpha = 0.2, add = TRUE, box = FALSE)
plot3d(ellips2, col = "forestgreen", alpha = 0.2, add = TRUE, box = FALSE)

虽然两个群体之间可以明显区分,但椭圆体相互接触。因此,椭圆体不是数据点的良好视觉表示。在2D绘图中,我更倾向于使用多边形whitch环绕所有数据点,但在3D中,像凸包一样的东西应该是足够的,即由三角形区域组成的多面体,每个区域组合三个外部数据点。

我认为在“几何”包中使用QuickHull算法的函数convhulln()会有所帮助,但我无法使用它。

有人知道如何在rgl情节中描绘这样的凸包吗?是否也可以使用plot3D包进行此操作,因为有一个很棒的教程here,我可以使用它来制作一个包含我自己数据的漂亮情节。

我“只是”使用R代表科学而不是数学家或R程序员的生物学家,所以请为我解释一下你的解决方案。非常感谢。

1 个答案:

答案 0 :(得分:2)

嘿,在这里找到了答案:

library("rgl")
data(iris)
x <- sep.l <- iris$Sepal.Length
y <- pet.l <- iris$Petal.Length
z <- sep.w <- iris$Sepal.Width
plot3d(x, y, z, col="blue", box = FALSE,
   type ="s", radius = 0.15)
ellips <- ellipse3d(cov(cbind(x,y,z)), 
                centre=c(mean(x), mean(y), mean(z)), level = 0.95)
plot3d(ellips, col = "blue", alpha = 0.2, add = TRUE, box = FALSE)

plot3d(x, y, z, col=c(rep("gold2",50),rep("forestgreen",100)), box = FALSE,
   type ="s", radius = 0.15)

在你上面做了什么后我添加了这个:

library(geometry)
ps1 <- matrix(c(x[1:50],y[1:50],z[1:50]), ncol=3)  # generate points on a sphere
ts.surf1 <- t(convhulln(ps1))  # see the qhull documentations for the options

convex1 <-  rgl.triangles(ps1[ts.surf1,1],ps1[ts.surf1,2],ps1[ts.surf1,3],col="gold2",alpha=.6)

ps2 <- matrix(c(x[51:150],y[51:150],z[51:150]), ncol=3)  # generate points on a sphere
ts.surf2 <- t(convhulln(ps2))  # see the qhull documentations for the options

convex2 <-  rgl.triangles(ps2[ts.surf2,1],ps2[ts.surf2,2],ps2[ts.surf2,3],col="forestgreen",alpha=.6)