Contact: Email: thomas.puschelrouliez@anthro.ox.ac.uk Web: thomas.puschel.com
Yesterday I received an email asking me how did I generate the 3D plots displayed in this preprint so I decided to share the process in this post. For this example I used the data from:
PĆ¼schel T. A., MarcĆ©-NoguĆ© J., Gladman J. T., Bobe R., & Sellers W. I. (2018). Inferring locomotor behaviours in Miocene New World monkeys using finite element analysis, geometric morphometrics and machine-learning classification techniques applied to talar morphology. Journal of The Royal Society Interface, 15(146), 20180520.
#1) Load the required packages
library('pca3d')
library('geomorph')
# for the colour palette
library('NineteenEightyR')
#2) Load the data
load('Talar_shape.RData')
#4) PCA biplot
PCA_morpho = prcomp(z, scale=F)
eig_m<-(PCA_morpho$sdev)^2
eig1_m<-(PCA_morpho$sdev[1])^2
eig2_m<-(PCA_morpho$sdev[2])^2
variance1_m<-eig1_m*100/sum(eig_m)
variance2_m<-eig2_m*100/sum(eig_m)
xlab <- paste('Principal Component 1', '(', round(variance1_m,digits=2), '%)')
ylab <- paste('Principal Component 2', '(', round(variance2_m,digits=2), '%)')
# plot PC1 vs PC2
plot(PCA_morpho$x[,1], PCA_morpho$x[,2], pch=tmp$pch, cex=2.5, bg = tmp$colors, xlab=xlab, ylab=ylab, asp=T)#
legend(-0.1,-0.04, bty = "n",legend= unique(tmp$Locomotion), pch=unique(tmp$pch), col=unique(tmp$colors), pt.bg=unique(tmp$colors), cex=0.5)
#5) Interactive PCA 3D
Additional information about the rgl
package can be found here
SH<-as.vector(c("sphere","cube","octahedron","tetrahedron"))
tmp$sh<-SH[as.numeric(as.factor(tmp$Locomotion))]
# Setup the background color
rgl.bg(color = "white")
#pca 3d
pca3d(pca=PCA_morpho, components = 1:3, col = tmp$colors, title = NULL,
new = FALSE,axes.color = "black", bg = "white", radius = 3.5,
group = tmp$Locomotion,shape=tmp$sh, show.axes = TRUE,show.axe.titles = TRUE,
axe.titles = NULL, show.plane = F,show.shadows = F, show.centroids = F,show.scale = T)
## [1] 0.008803568 0.004052094 0.004235430
# Groups
groups <- as.factor(tmp$Locomotion)
levs <- levels(groups)
group.col <- c(malibu(4))
#
x<-PCA_morpho$x[,1]
y<-PCA_morpho$x[,2]
z<-PCA_morpho$x[,3]
# Compute 95% CI ellipse for each one of the groups
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 = group.col[i], alpha = 0.1, lit = FALSE)
# show group labels
# texts3d(mean(xx),mean(yy), mean(zz), text = group,
# col= group.col[i], cex = 2)
}
aspect3d(1,1,1)
rglwidget(webgl=TRUE, snapshot=FALSE)