Изображение Выпуклая оболочка в 3D Scatter Plot
Я следовал учебнику о 3D визуализации, используя пакет "rgl" здесь
Таким образом, я смог нарисовать трехмерную диаграмму рассеяния с данными "радужной оболочки" и создать эллипсоид, окружающий 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 графике я бы предпочел использовать полином, который окружает все точки данных, но в 3D должно быть адекватным что-то вроде выпуклой оболочки, то есть многогранник, состоящий из областей треугольника, которые объединяют три внешние точки данных каждая.
Я думаю, что функция convhulln(), использующая алгоритм QuickHull в пакете "geometry", была бы полезна, но я не могу использовать это.
У кого-нибудь есть идея, как изобразить такой выпуклый корпус на графике rgl? Возможно ли это сделать с помощью пакета plot3D, поскольку здесь есть отличное учебное пособие, которое я мог бы использовать для создания прекрасного графика с моими собственными данными.
Я "всего лишь" биолог, использующий R для науки, а не математик или программист на R, поэтому, пожалуйста, объясните мне свое решение. Большое спасибо.
1 ответ
Эй, узнал ответ здесь:
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)