Tips & Tricks 9: Shape Changes and Hypothetical Shapes

June 18, 2015
By

(This article was first published on geomorph, and kindly contributed to R-bloggers)

Geomorph users,

This month’s tips and tricks was prompted by a user email from Tim Astrop, thanks Tim!


How can I create a hypothetical shape representing a point in shape space?

Today we will use some relatively simple R code to create a shape based on position in a Principal Component (PC) shape space and visualise this shape as a change from the mean using plotRefToTarget().

Exercise 9 – Creating hypothetical shapes


When you use plotTangentSpace() to visualise the variation among individuals in your dataset, two thin-plate spline (tps) deformation grids are plotted by default:
> data(plethodon)
> Y.gpa<-gpagen(plethodon$land)    #GPA-alignment
> gp <- as.factor(paste(plethodon$species, plethodon$site))

> PCA <- plotTangentSpace(Y.gpa$coords, groups = gp, verbose=T)

plotTangentSpace() example using plethodon dataset

These represent the shape change between the mean and the minimum PC1 score or maximum PC1 score. This is why the arrows point to the coordinates (max(PC1), 0) and (min(PC1), 0). They are made from the hypothetical shapes at the ends of the PC1 axis.

When you use verbose = T, a list called $pc.shapes is returned. In this list are the coordinates for the shapes at the minima and maxima of the two axes used in the plot (default PCs 1 and 2). These are returned so that you can plot these tps grids yourself using plotRefToTarget(), e.g.:

> ref <- mshape(Y.gpa$coords) # get mean shape

> plotRefToTarget(ref, PCA$pc.shapes$PC1max, method = “tps”)
> PCA$pc.shapes$PC1max
             [,1]         [,2]
 [1,]  0.14208576 -0.022246055
 [2,]  0.17904134 -0.088344179
 [3,] -0.02011384 -0.002132243
 [4,] -0.28076578 -0.088499525
 [5,] -0.30905960 -0.061152408
 [6,] -0.32381908 -0.036119622
 [7,] -0.31939430  0.031269185
 [8,] -0.19235878  0.099093107
 [9,]  0.01443297  0.106911342
[10,]  0.18138128  0.077532805
[11,]  0.39536788  0.058597759
[12,]  0.53320215 -0.074910167


How do we make this matrix above? 
First we do a PCA:
> pc.res <- prcomp(two.d.array(Y.gpa$coords))
> pcdata <- pc.res$x # save the PC scores
> rotation <- pc.res$rotation # save the rotation matrix

> k <- dim(Y.gpa$coords)[2] ; p <- dim(Y.gpa$coords)[1] # set number of dimensions and number of landmarks

Then we find the maximum value on PC1, first column of the pcdata matrix
> pcaxis.max.1 <- max(pcdata[, 1]) # find the maximum value on PC1, first column of the pc.scores
> pcaxis.max.1
[1] 0.05533109
Then we will create the shape at the point where max(PC1) and all other PCs are 0:
> pc.vec <- rep(0, dim(pcdata)[2]) # makes a vector of 0s as long as the number of PCs
pc.vec
 [1] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
pc.vec[1] <- pcaxis.max.1 # put the value into this vector
pc.vec
 [1] 0.05533109 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000
 [8] 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000
[15] 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000
[22] 0.00000000 0.00000000 0.00000000
> PC1max <- arrayspecs(as.matrix(pc.vec %*% (t(rotation))), p,k)[,,1] + ref 
Above we are doing a matrix multiplication (%*%) of the vector pc.vec and the transpose of the rotation matrix, making it into a p x k matrix using our arrayspecs function, and then adding in the mean shape we made earlier, so:
> PC1max
             [,1]         [,2]
 [1,]  0.14208576 -0.022246055
 [2,]  0.17904134 -0.088344179
 [3,] -0.02011384 -0.002132243
 [4,] -0.28076578 -0.088499525
 [5,] -0.30905960 -0.061152408
 [6,] -0.32381908 -0.036119622
 [7,] -0.31939430  0.031269185
 [8,] -0.19235878  0.099093107
 [9,]  0.01443297  0.106911342
[10,]  0.18138128  0.077532805
[11,]  0.39536788  0.058597759
[12,]  0.53320215 -0.074910167

The important part above is the pc.vec[1] <- pcaxis.max.1
If we had specified min of PC3, then it would be:

 [1]  0.00000000  0.00000000 -0.05190833  0.00000000  0.00000000  0.00000000
 [7]  0.00000000  0.00000000  0.00000000  0.00000000  0.00000000  0.00000000
[13]  0.00000000  0.00000000  0.00000000  0.00000000  0.00000000  0.00000000
[19]  0.00000000  0.00000000  0.00000000  0.00000000  0.00000000  0.00000000

In this way, it is possible to create any shape in the PC shape space, simply by adding in the coordinates into the vector we call here pc.vec.

Further reading: Rohlf, F.J., 1996. Morphometric spaces, shape components and the effects of linear transformations. In L. F. Marcus et al., eds. Advances in Morphometrics. NY: Plenum Press, pp. 117–130.

Enjoy!
Emma

To leave a comment for the author, please follow the link and comment on their blog: geomorph.

R-bloggers.com offers daily e-mail updates about R news and tutorials on topics such as: Data science, Big Data, R jobs, visualization (ggplot2, Boxplots, maps, animation), programming (RStudio, Sweave, LaTeX, SQL, Eclipse, git, hadoop, Web Scraping) statistics (regression, PCA, time series, trading) and more...



If you got this far, why not subscribe for updates from the site? Choose your flavor: e-mail, twitter, RSS, or facebook...

Comments are closed.

Search R-bloggers


Sponsors

Never miss an update!
Subscribe to R-bloggers to receive
e-mails with the latest R posts.
(You will not see this message again.)

Click here to close (This popup will not appear again)