In this tutorial, we demonstrate some of the graphical capabilities
of geomorph that may be used to visualize patterns of shape
variation, and interpret particular shape differences between specimens.
These types of plots, shape difference plots and principal components
plots, are found in nearly every empirical publication using geometric
morphometric shape data, and are thus of primary importance.
Geomorph now has considerable flexibility in plot options
for these visualizations, and we encourage you to explore these options
and consult the help pages of the various functions.
First, let´s load some example data and plot the specimens (before and after GPA alignment):
# library(geomorph)
# data(plethodon)
# Y.gpa <- gpagen(plethodon$land, print.progress = F) # GPA-alignment
#
# par(mfrow=c(1,2))
# plotAllSpecimens(plethodon$land, links=plethodon$links) # Raw data
# mtext("Raw Data")
# plotAllSpecimens(Y.gpa$coords, links=plethodon$links) # GPA-aligned data
# mtext("GPA-Aligned Specimens")
# par(mfrow=c(1,1))
Visualizing shape deformations is ALWAYS relative to
some reference. That is, we provide graphical depictions of shape
differences \(\small{Reference\rightarrow{Target}}\).
Typically, we use the overall average as a reference, and deform it into
some target using the function plotRefToTarget. There are
quite a few plotting options available: a few of them are illustrated
here (but see the help files for more details!).
**Here we demonstrate several shape deformation plots as found in
geomorph
Deformations Specimen to Specimen
# ref <- mshape(Y.gpa$coords)
#
# plotRefToTarget(ref,Y.gpa$coords[,,39], links=plethodon$links)
# mtext("TPS")
# plotRefToTarget(ref,Y.gpa$coords[,,39], mag=2.5, links=plethodon$links)
# mtext("TPS: 2.5X magnification")
# par(mfrow=c(1,1))
#
# plotRefToTarget(ref,Y.gpa$coords[,,39], links=plethodon$links, method="vector", mag=3)
# mtext("Vector Displacements")
# plotRefToTarget(ref,Y.gpa$coords[,,39], links=plethodon$links,gridPars=gridPar(pt.bg="red", link.col="green", pt.size = 1), method="vector", mag=3)
# mtext("Vector Displacements: Other Options")
#
# plotRefToTarget(ref,Y.gpa$coords[,,39], mag=2, outline=plethodon$outline)
# mtext("Outline Deformation")
# plotRefToTarget(ref,Y.gpa$coords[,,39], method="points", outline=plethodon$outline)
# mtext("Outline Deformations Ref (gray) & and Tar (black)")
Many times, we wish to visualize shape deformations based on a particular statistical model. For instance, we may wish to visualize group differences from ANOVA, or visualize how shape changes along some axis, like a regression line or a PC-axis. All of these require Predicting shapes based on some mathematical model, and then visualizing shape deformations using those predicted shapes.
While the mathematics of this can become rather involved, it is
straightforward. Fortunately, geomorph has a wonderful and
general function to accomplish this task: shape.predictor.
Here we demonstrate a few of its capabilities (**NOTE: in future
lectures we will discuss the mathematics of these statistical methods.
Here the visualization tools only are demonstrated):
PCA Shape Predictions
# M <- mshape(Y.gpa$coords)
# PCA <- plotTangentSpace(Y.gpa$coords)
# PC <- PCA$pc.scores[,1]
# preds <- shape.predictor(Y.gpa$coords, x= PC, Intercept = FALSE,
# pred1 = min(PC), pred2 = max(PC)) # PC 1 extremes, more technically
# plotRefToTarget(M, preds$pred1, links = plethodon$links)
# mtext("PC1 - Min.")
# plotRefToTarget(M, preds$pred2, links = plethodon$links)
# mtext("PC1 - Max.")
Shape Predictions Along a Regression
Many times, we fit a linear model in the form of regression (e.g.,
allometry). Here is how we visualize shape changes along the extremes of
that regression using shape.predictor:
# gdf <- geomorph.data.frame(Y.gpa)
# plethAllometry <- procD.lm(coords ~ log(Csize), data=gdf, print.progress = FALSE)
# allom.plot <- plot(plethAllometry,
# type = "regression",
# predictor = log(gdf$Csize),
# reg.type ="PredLine") # make sure to have a predictor
#
# preds <- shape.predictor(plethAllometry$GM$fitted, x= allom.plot$RegScore, Intercept = FALSE,
# predmin = min(allom.plot$RegScore),
# predmax = max(allom.plot$RegScore))
# plotRefToTarget(M, preds$predmin, mag=3, links = plethodon$links)
# plotRefToTarget(M, preds$predmax, mag=3, links = plethodon$links)
Shape Predictions of Group Differences
Another very common statistical design is one of evaluating group differences in shape (i.e., ANOVA). Here we wish to visualize shape differences among groups. Below is an example:
# gdf <- geomorph.data.frame(Y.gpa, species = plethodon$species, site = plethodon$site)
# pleth.anova <- procD.lm(coords ~ species*site, data=gdf, print.progress = FALSE)
# X <- pleth.anova$X
# X # includes intercept; remove for better functioning
# X <- X[,-1]
# symJord <- c(0,1,0) # design for P. Jordani in sympatry
# alloJord <- c(0,0,0) # design for P. Jordani in allopatry
# preds <- shape.predictor(arrayspecs(pleth.anova$fitted, 12, 2), x = X, Intercept = TRUE,
# symJord=symJord, alloJord=alloJord)
# plotRefToTarget(M, preds$symJord, links = plethodon$links, mag=2)
# plotRefToTarget(M, preds$alloJord, links = plethodon$links, mag=2)
In geomorph, there are two ways to obtain a principal
components plot of shape variation (i.e, a visualization of Tangent
Space). Here is the first option, using
plotTangentSpace:
# plotTangentSpace(Y.gpa$coords, groups = interaction(plethodon$species, plethodon$site))
Alternatively, one could use the function gm.prcomp.
This has additional flexibility as compared to the previous function,
some of which we show here (later we will show phylogenetic PCA
plots):
# pleth.raw <- gm.prcomp(Y.gpa$coords)
#
# gps <- as.factor(paste(plethodon$species, plethodon$site))
# plot(pleth.raw)
# par(mar=c(2, 2, 2, 2))
# plot(pleth.raw, pch=22, cex = 1.5, bg = gps)
# # Add things as desired using standard R plotting
# text(par()$usr[1], 0.1*par()$usr[3], labels = "PC1 - 36.74%", pos = 4, font = 2)
# text(0, 0.95*par()$usr[4], labels = "PC2 - 31.02%", pos = 4, font = 2)
# legend("topleft", pch=22, pt.bg = unique(gps), legend = levels(gps))
One recent enhancement of geomorph is the
picknplot.shape function. With this function, one can
select locations in a statistical dataspace, and geomorph
will mathematically back-translate the statistical summary values in the
plot to obtain landmark coordinates, and will then generate a thin-plate
spline deformation grid of a specimen that would exist at that location
in the dataspace.
This real-time visualization is especially useful for viewing regions of morphospace that are unoccupied by the sample of specimens, and for exploring other non-sampled shapes.
# 2d
# data(plethodon)
# Y.gpa <- gpagen(plethodon$land)
# pleth.pca <- gm.prcomp(Y.gpa$coords)
# pleth.pca.plot <- plot(pleth.pca)
# picknplot.shape(pleth.pca.plot)
# May change arguments for plotRefToTarget
# picknplot.shape(plot(pleth.pca), method = "points", mag = 3, links=plethodon$links)
Geomorph also has the ability to generate shape
deformations of 3D objects. Again this is interactive code, so it is
repeated, but not run, below:
#scallops <- readland.tps("Data/scallops for viz.tps", specID = "ID")
#ref <- mshape(scallops)
#refmesh <- warpRefMesh(read.ply("Data/glyp02L.ply"),
# scallops[,,1], ref, color=NULL, centered=T)
#plot.gm.prcomp(scallops, axis1 = 1, axis2 = 2, warpgrids=T, mesh= refmesh)