-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsource.r
78 lines (72 loc) · 2.71 KB
/
source.r
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
require(rgl)
#Main and only function
#
#This function shows an animation of a 3d plot.
#x,y,z are the three axis.
#groups is a vector containing the cluster each instance is in.
#truth is the ground truth, used to plot misclassified points.
#axis_n contains the lables of the three axis.
plot_3d<-function(x,y,z,groups=1,truth=groups, axis_n=c("x","y","z"), spin = TRUE){
rgl_init <- function(new.device = FALSE, bg = "white", width = 640) {
if( new.device | rgl.cur() == 0 ) {
rgl.open()
par3d(windowRect = 50 + c( 0, 0, width, width ) )
rgl.bg(color = bg )
}
rgl.clear(type = c("shapes", "bboxdeco"))
rgl.viewpoint(theta = 15, phi = 20, zoom = 0.7)
}
rgl_add_axes <- function(x, y, z, axis.col = "grey",
xlab = axis_n[1], ylab=axis_n[2], zlab=axis_n[3], show.plane = TRUE,
show.bbox = TRUE, bbox.col = c("#333377","black"))
{
lim <- function(x){c(-max(abs(x)), max(abs(x))) * 1.1}
# Add axes
xlim <- lim(x); ylim <- lim(y); zlim <- lim(z)
rgl.lines(xlim, c(0, 0), c(0, 0), color = axis.col)
rgl.lines(c(0, 0), ylim, c(0, 0), color = axis.col)
rgl.lines(c(0, 0), c(0, 0), zlim, color = axis.col)
# Add a point at the end of each axes to specify the direction
axes <- rbind(c(xlim[2], 0, 0), c(0, ylim[2], 0),
c(0, 0, zlim[2]))
rgl.points(axes, color = axis.col, size = 3)
# Add axis labels
rgl.texts(axes, text = c(xlab, ylab, zlab), color = "purple",
adj = c(0.5, -0.8), size = 2)
# Add bounding box decoration
if(show.bbox){
rgl.bbox(color=c(bbox.col[1],bbox.col[2]), alpha = 0.5,
emission=bbox.col[1], specular=bbox.col[1], shininess=5,
xlen = 3, ylen = 3, zlen = 3)
}
}
levs=levels(as.factor(groups))
rgl_init()
ellipse_col <- c("red", "green", "blue","brown","yellow")
if(truth!=groups){
pch3d(x, y, z, pch = ifelse(groups==data[,1],20,15),
bg = material3d("color")[1], cex = 1, color = groups, lit = FALSE)
}
else{
rgl.spheres(x, y, z, r = 0.1, color = groups)
}
rgl_add_axes(x, y, z, show.bbox = TRUE)
for (i in 1:length(levs)) {
group <- levs[i]
selected <- groups == group
xx <- x[selected]; yy <- y[selected]; zz <- z[selected]
ellips <- ellipse3d(cov(cbind(xx,yy,zz)),
centre=c(mean(xx), mean(yy), mean(zz)), level = 0.95)
shade3d(ellips, col = ellipse_col[i], alpha = 0.1, lit = FALSE)
# show group labels
texts3d(mean(xx),mean(yy), mean(zz), text = group,
col= ellipse_col[i], cex = 1)
}
aspect3d(1,1,1)
if (spin)
{
require(magick)
movie3d(spin3d(axis = c(0, 1, 0)), duration = 10,
dir = getwd())
}
}