Geometric Morphometric Analyses of 2D/3D Landmark Data

Read, manipulate, and digitize landmark data, generate shape variables via Procrustes analysis for points, curves and surfaces, perform shape analyses, and provide graphical depictions of shapes and patterns of shape variation.

Geomorph is a software package for performing all stages of geometric morphometric shape analysis of 2- and 3-dimensional landmark points, as well as semilandmarks on curves and surfaces, in the R statistical computing environment. This repository is dedicated to providing beta versions between CRAN uploads.

Details of the installion can be found here: .

Details on how to get started can be found on the geomorph wiki: .

To install the current geomorph R-package from CRAN:

Within R:


To install the current version of geomorph R-package from Github using devtools:

Within R:


devtools::install_github("geomorphR/geomorph",ref = "Stable")

This installs a stable release of the current version of geomorph on CRAN, allowing us to quickly fix errors that slip thorugh the cracks and are uploaded with the CRAN version.

To install the Development version (beta) of geomorph R-package from Github using devtools:

Within R:


devtools::install_github("geomorphR/geomorph",ref = "Develop")

NOTE FOR THE PRE-RELEASE (BETA) VERSION: We strongly discourage you from publishing results with this version, unless you check with the authors first.


CHANGES IN GEOMORPH VERSION 3.0.7 o Modified output in bilat.symmetry so output shapes retain order in 'ind' factor o Modified readland.tps to identify missing data only when all lm coordinates are <0 and interactively prompt the user to confirm if they are to be treated as NAs o Fixed readland.tps whitespace delimitation o RRPP package now used for computations in advanced.procD.lm

CHANGES IN GEOMORPH VERSION 3.0.6 NEW FEATURES o plotOutliers now allows to plot outlier configurations in order to compare their shape with the consensus o plot.mshape function added to plot the consensus configuration with numbers and links

OTHER CHANGES o Modified previous addition to readland.tps to identify missing data only when all lm dimensions are <0 and interactively prompt the user to confirm if they are to be treated as NAs.
o Added ellipsis to bilat.symmetry and geomorphShapes option to allow more flexible gpagen options within o Changed procD.pgls to use residuals from GLS model for permutations o Added effect type option to advanced.procD.lm o Added an additional line of summary to ANOVA tables to signal how effect sizes are calculated o Adjusted ANOVA tables to show from which distributions P-values are estimated o Modified plot.procD.allometry to allow direct control of all plotting arguments by the user o Modified plotRefToTarget and tps to use plot.xy instead of plot, and thus avoid conflicts with plot.mshape o Added catch for missing data to readland.tps, to identify negative values and recode them as NAs

BUG FIXES o Fixed issue with compare.evol.rates permutation method for univariate trait o Fixed issues with estimate.missing regression approach o Fixed issues with phylo.integration where Y-dataset contained a single variable o Fixed issue with integration.test when 3+ partitions with non-contiguous variables o Fixed effect size calculation error in procD.lm for single factor OLS models. o Fixed ellipses options in

CHANGES IN GEOMORPH VERSION 3.0.5 OTHER CHANGES o Simplified options available in procD.allometry

BUG FIXES o Fixed CAC calculations in procD.allometry o Fixed dimnames error in readland.nts when file contained a single specimen's data o Fixed PGLS weights for factors in morphol.disparity when phylogeny utilized o Fixed readland.tps to be general to whitespace delimitation

CHANGES IN GEOMORPH VERSION 3.0.4 NEW FEATURES o An option to use types I, II, or III sums of squares and cross-products for ANOVA analyses (e.g., procD.lm, procD.pgls) o PGLS option for advanced.procD.lm o An option to choose between SS, F-values, or Cohen's f-squared to calculate effect sizes for ANOVA analyses. o Effect sizes are now centered on mean values from distributions of random statistics. Statistics are also log-transformed in certain cases to normalize distributions. o An option to use only an intercept as a model for procD.lm and procD.pgls, with limited output. o An option to use permutation tests when comparing net evolutionary rates for compare.evol.rates o New function interlmkdist to calculate linear distances between landmarks

OTHER CHANGES o Enhanced landmark labeling in arrayspecs. o Created transferability of dimnames between arraysepcs and two.d.array. o Updated Rd files for PLS functions to better cross-reference the similar functions. o Added data frame output to procD.lm o Change to plotGMPhyloMorphoSpace to center data by phylogenetic mean o read.morphologika now supports lists of file names to return a single data object o Updated Rd files for readland.nts and readmulti.nts to avoid ambiguity and resolve misinformation in previous versions o Updated readland.nts to accept specimen labels with spaces in name

BUG FIXES o Fixed grids in tps to match reference not target, so that points are in the correct cells o Fixed univariate PLS to allow negative correlations o Fixed permutation issues with advanced.procD.lm o Fixed links not plotting in plotAllSpecimens if no colour specified o Added missing random.r output to integration.test and phylo.integration


NEW FEATURES o New functions: compare.pls, coords.subset, shape.predictor o added to support code

OTHER CHANGES o Added a sensor to support code for procD.lm and its allies to choose the computationally fastest algorithms based on design matrix complexity and data dimnesionality o Updated to remove unused levels from factors o Updated all functions using to drop unused factor levels o Updated mshape to be used on lists, arrays, or matrices

BUG FIXES o Fixed single.factor function to properly maintain factor levels when combining factors o Fixed plotting issues with phylo.integration


NEW FEATURES o Added return of min/max shape matrices to plot.procD.allometry() and plot.pls() o Added option to save specimen ID to ID= line in writeland.tps() o Added option to hide axes in plotRefToTarget()

OTHER CHANGES o Continued optimization of analytical functions for faster computations o Added force match of specimen order between blocks in two.b.pls() o Updated A, Ahat, ref, p and k outputs when 2D matrix is used in procD.allometry() o Added option to plot group labels in plot.procD.allometry(method="PredLine") o Added legend option to plotTangentSpace() when groups are specified o Removed 'verbose' from plotTangentSpace(); function now returns PC scores automatically when assigned to object o Updated plotTangentSpace() to return min and max shapes for all PC axes in $pc.shapes

BUG FIXES o Fixed label output issue with bilat.symmetry shape components o Fixed error plotting TPS grids when groups were included in plot.procD.allometry() o Fixed error in digit.curves() where open outline would be treated as closed if starting point was the end point o Fixed reading of ape::chronos phylogenies in 'phylo' functions o Fixed error in reading names in readland.tps() for some tps files


OTHER CHANGES o Removed dependency on phytools o Small addition to outputs in procD.pgls() o added reading polygons in read.morphologika()

BUG FIXES o Fixed label output for matrices in bilat.symmetry o Fixed output formatting of pairwise pvalue matrix in compare.evol.rates o Fixed error in output order in plotOutliers o Fixed error in calculation slope distances in advanced.procD.lm
o Fixed 2D data input error for phylo.modularity o Fixed centering error for CAC scores in procDAllometry o Fixed deformation plot issue with phylo.integration (via plot.pls) o Fixed two small issues with plot.pls, regarding best fit line and matrix reduction. o Fixed generalized inverse for tps2d() o Fixed three small issues with gpagen source files: indexing errors, arbitrary PC rotations for surface points, maximum iteration disparity. o Fixed digitize2D() scaling issue when different scales used in each image o Fixed phylo.integration() error when 3+ partitions examined o Fixed typo in modularity.test() for CI intervals into matrix input o Updated permutation procedure in phylo.integration so that prob(A,B|phy)~prob(B,A|phy)


NEW FEATURES o New functions: modularity.test(), integration.test(), phylo.modularity(), phylo.integration(), procD.allometry(), nested.update(), o Seed option added for most analytical functions o Major overhaul of underlying support code for analytics o Output from analytical functions provided in lists o Added 'summary' option to most analytical functions o Plotting for most analytical functions as 'plot(res)' if res is output from function o Diagnostic plots for anova/regression added o Nested ANOVA via nested.update() of procD.lm() objects

OTHER CHANGES o Deprecated: compare.modular.partitions(), morphol.integr(), phylo.pls(), and plotAllometry() o Removed internal C-code for gpagen() o Removed automatic plots for most analytical functions o Removed method="" parameter from physignal(). Only Kmult used o Removed verbose option for most functions: all output provided in lists o Added option to pre-multiply coordinates by scale in digitize2d() o Added plotting options to plotAllSpecimens()

BUG FIXES o Fixed morphol.disparity()$Prob.Disp displaying NAs


BUG FIXES o Fixed small change in C-code for gpagen()


NEW FEATURES o New function compare.multi.evol.rates() for comparing rates of evolution among traits o plotGMPhyloMorphoSpace() now plots 3D phylomorphospaces and chronophylomorphospaces o Added ShowPlot option to bilat.symmetry(), compare.modular.partitions(), globalIntegration(), morphol.integr(), and phylo.pls()

o Updated Imports packages as per new CRAN policies o Small change to C-code for gpagen (added additional checks on alignment) o Package ape now full Import for geomorph (no longer ImportsFrom) o Enhanced input flexibility for advanced.ProcD.lm(): for single-factor analyses and matrix/variable input o Enhanced readland.nts() flexibility with specimen labels; now supports spaces in labels o Generalized read.ply() to allow reading meshes with many properties o Generalised input for physignal() and compare.evol.rates(): univariate data accepted as named vector o Enhanced input for define.links(): read and append links to existing links matrix

BUG FIXES o Corrected error in warpRefMesh() where normals were incorrectly assigned to new mesh3d object o Corrected error in readland.tps() which read in a file containing a single specimen returned a 2D matrix rather than 3D array; this fixes the issue with digitize2d not working for a single file o Corrected error in morphol.integr() where warpgrids = F did not work for 3D datasets o Corrected issue with globalIntegration for use with 3D data o Corrected bug in plotRefToTarget method = "TPS" where the wrong options from gridPars were being passed


NEW FEATURES o New globalIntegration() function for evaluating integration vs. self-similarity of shape variation o Coordinates returned by digitize2d() are now unscaled, and SCALE= returns the scale

o Phylogenetic simulation procedure in compare.evol.rates() generalized to use a single evolutionary rate matrix o pairwiseD.test() and pairwise.slope().test now defunct o define.sliders.2d() and define.sliders.3d() now defunct o read.morphologika() can read files with missing data o Ability to not show plot added to physignal() and compare.evol.rates()

BUG FIXES o Corrected error in defining starting point in digit.curves()


NEW FEATURES o ability to include pre-digitized landmarks added to build.template() and digitsurface() o new gridPar() is a new function to customize plots of plotRefToTarget o new digit.curves() is a new function to calculate equidistant semilandmarks along 2D and 3D curves o define.sliders() is new interactive function for defining sliding semilandmarks for 2D and 3D curves, plus an automatic mode when given a sequence of semilandmarks along a curve

BUG FIXES o Corrected an error in plotAllometry() where verbose=T did not return

OTHER CHANGES o pairwiseD.test() and pairwise.slope.test() deprecated o 'read' functions now allow both tab and space delimited files o define.sliders.2d() and define.sliders.3d() deprecated (replaced by define.sliders)


OTHER CHANGES o warpRefMesh() generalised - now takes a mesh3d object (i.e. made from read.ply()) rather than calling read.ply() directly o read.morphologika() now reads [groups] option and adds these data to the $labels matrix o plotOutliers() now has option groups to plot outliers by levels(groups) using group means o morphol.disparity() help file updated to correctly indicate that group shape residuals, rather than shape values, themselves, are randomized in the permutation procedure o Internal changes to support functions for compatibility with R 3.1.3 o Generalized plot inputs in gpagen()

BUG FIXES o Corrected error readland.tps() o Corrected errors trajectory.analysis() o Corrected an issue with gpagen() that flipped principal axes o Fixed error in read.morphologika() with reading [wireframe] in some morphologika files


NEW FEATURES o new plotOutliers() function to identify potential outliers o new define.links() function for enhanced plotting of shapes

OTHER CHANGES o Additional input options added to pairwiseD.test() and pairwise.slope.test() o Ability to accommodate singular phylogenetic covariance matrices in: physignal(), compare.evol.rates(), procD.pgls() and phylo.pls() o Enhanced digitizing capability in: build.template(), define.modules(), define.sliders.3d(), digit.fixed(), digitsurface(), and editTemplate() ) o plotAllometry() input can be 2D matrix or 3D array o read.ply() reads normals for enhanced downstream digitizing from ply files o readland.tps() reads curves from tps files and convert them to landmarks (semilandmarks) o plotTangentSpace() has enhanced plotting flexibility with labels and colors

BUG FIXES o Corrected error printing output of ANOVA table of bilat.symmetry() o Removed redundant permutation loop in phylo.pls()


NEW FEATURES o New function advanced.procD.lm() for statistically comparing two or explanatory models o Added warping of outline in plotRefToTarget() o New function to warp a specimen outline to the reference: warpRefOutline() o Added ShowPlot option to two.b.pls o Added RRPP option to procD.pgls() o New dataset pupfish

BUG FIXES o Fixed output of procD.lm() when verbose=TRUE o Fixed reflections of aligned coordinate axes when PrinAxes=TRUE in gpagen()

OTHER CHANGES o Enhanced underlying code in procD.lm(), procD.pgls() pairwiseD.test() and pairwise.slope.test() o Removed k>3 restriction in arrayspecs() o Added is.numeric check to phylo.pls() o Removed arrows from plots when groups included in plotAllometry()


BUG FIXES o Fixed concatenated SSCP matrix issue in procD.lm(), pairwise.D.test() and pairwise.slope.test() o Corrected issue reading specimen names in readland.tps() o Corrected color options for plotting groups in plotTangentSpace() o Corrected test for slope:group interaction in plotAllometry()

NEW FEATURES o Specimens rotated to their principal axes in gpagen() with option to disable

OTHER CHANGES o Underlying code for ancestral state estimation changed to use fastAnc (phytools)


NEW FUNCTIONS o procD.pgls() added to assess high-dimensional ANOVA and regression models in a phylogenetic context o pairwise.slope.test() added to compare slopes of regression lines

NEW FEATURES o Residual randomization options added to procD.lm() and pairwise.d.test() o Enhanced capabilities of digitize2d(). Function now reads multiple images and outputs TPS file, can be used with missing data, and digitizing session can be restarted where previous session stopped.

BUG FIXES o Fixed scale issue in digitize2d()

OTHER CHANGES o Ability to plot specimen labels added to two.b.pls(), morphol.integr(), and phylo.pls() o Slight ANOVA table output adjustment in bilat.symmetry() o Vector of labels can be added for plotting in plotAllometry() and plotTangentSpace() o Labels for ancestral states addd to plotGMPhyloMorphoSpace()

CHANGES IN GEOMORPH VERSION 2.0.1 o Small change to C-code for gpagen


NEW FEATURES o New function phylo.pls() for assessing the multivariate association between two blocks of variables in a phylogenetic context o New function two.b.pls() for assessing the multivariate association between two blocks of variables o New function morphol.disparity() to compare Procrustes variance disparity among groups o F-ratios and R-squared values added to output of ProcD.lm() o 3D Visualizations now include "surface" option to view shape deformation as warped mesh3d surfaces in the following: plotRefToTarget(), plotTangentSpace(), plotAllometry(), and bilat.symmetry() o New I/O functions: warpRefMesh() to create a mesh3d surface that represents the mean shape, findMeanSpec() to assist in choosing a template ply file for use with warpRefMesh that identifies specimen closest to the mean shape, and defline.modules() to interactively assign landmarks to modular partitions [currently 2D only] o Generalized data input to allow 3D array or 2D matrix of data added to the following analysis functions: compare.evol.rates(), phylo.pls(), morphol.integr(), two.b.pls(), physignal(), and plotGMPhyloMorphoSpace() o Ability to input univariate data added to compare.evol.rates() and physignal() o Verbose output = T/F added to the following functions: bilat.symmetry(), phylo.pls(), two.b.pls(), morphol.integr(), plotAllometry(), plotTangentSpace(), physignal()

OTHER CHANGES o Added calculation of pairwise Pvalues, and the option to assess a single group in function compare.evol.rates() o Additional graphical output added to morphol.integr() o Missing data handling altered (now NA is used) o byLand option in arrayspecs() has been removed o Residual shape component (RSC) plot added and scores returned for plotAllometry (method = "CAC") o Procrustes ANOVA added to plotAllometry output o Centering = T/F option added to following 3D digitizing functions: build.Template(), digit.fixed(), digitsurface(), and plotSpec() o read.vrml now defunct

INTERNAL CODING CHANGES o Major re-organization of underlying R code structure and format o Optimized code to improve speed and performance in following functions: arrayspecs(), readland.tps(), readland.nts(), readmulti.nts(), two.d.array(), plotTangentSpace(), trajectory.analysis(), bilat.symmetry(), gpagen() o Simplified plotting options in bilat.symmetry()

BUG FIXES o Corrected small coding error in digitize2D and updated flexibility of the function


OTHER CHANGES o Minor I/O enhancements in readmulti.nts() o Minor I/O enhancements in define.sliders.3d() to allow sliders to be in any order o Simplified pPsup (original code from J. Claude) to not include size re-scaling by beta (underlying function used in trajectory.analysis() only) o Added name.check for groups in compare.evol.rates()


NEW FEATURES o New function compare.evol.rates() for comparing multivariate evolutionary rates on phylogenies o define.sliders.2d() and define.sliders.3d() replace curves2d() and digit.curves() o Option allowing specimens to be colored by group added to plotTangentSpace() and PlotAllometry()

BUG FIXES o Corrected parameter estimates when groups specified for Regression Score option in plotAllometry()

OTHER CHANGES o Simplified options in morphol.integr() o curves2d() and digit.curves() deprecated


NEW FEATURES o Enhanced plotting of ply files in read.ply() o digitsurface(), buildtemplate(), plotspec(), digitfixed(), and digitcurves() now support ply file input

OTHER CHANGES o Minor changes to plot window options in plotting functions o Change to magnification factor usage in plotRefToTartget()


OTHER CHANGES o Improved NAMESPACE file and package usage o Generalized read.vrml() code for additional file formats


NEW FEATURES o pairwiseD.test() function added o bilat.symmetry() output includes symmetric and asymmetric shape components

BUG FIXES o Corrected readland.tps() to allow for non-numeric ID and reading a single specimen per file o Corrected landmark plotting issue and added greater directory flexibility in curves2D() o Added greater directory flexibility and fixed header output in digitize2D() o Added greater flexibility in reading distinct file formats in read.morphologika() o Corrected angle calculations in fixed.angle() o Corrected plotting of deformations grids in plotTangentSpace() o Corrected ancestral state output in physignal() and PlotGMPhyloMorphoSpace()

OTHER CHANGES o Adjusted plotting routines in morphol.integr() to be compatible with new CRAN guidelines o Adjusted plotting routines in bilat.symmetry() to be compatible with new CRAN guidelines o Alternative ancestral state reconstruction and tests for bifurcating tree implemeneted in physignal() o Alternative ancestral state reconstruction and tests for bifurcating tree implemeneted in PlotGMPhyloMorphoSpace()

CHANGES IN GEOMORPH VERSION 1.1-1 o Removed dependency in physignal() on getAncStates() from geiger, which is no longer supported o Removed dependency in plotGMPhyloMorphoSpace() on getAncStates() from geiger, which is no longer supported


NEW FEATURES o bilat.symmetry() function added o writeland.tps() function added o fixed.angle() function added o compare.modular.partitions() generalized to allow 2 or more partitions o morphol.integr() generalized to allow 2 or more partitions o trajectory.analysis() re-written to accept formulas, allowing greater flexibility for motion analysis o PLS scores added to output morphol.integr() o Ancestral states added to output physignal() o Centroid size and allometry scores added as output in plotAllometry() o PC scores added to output of plotTangentSpace() o Option added to select PC axes for plot in plotTangentSpace() o Option added to include specimen numbers to plotTangentSpace()

BUG FIXES o buildtemplate() positional error in plot between template and scan corrected o digit.curves() error with passing objects to internal function corrected o gpgen() occassional reflection issue corrected

OTHER CHANGES o read.morphologika() accepts greater variety of input file formats

Reference manual

It appears you don't have a PDF plugin for this browser. You can click here to download the reference manual.


4.0.1 by Dean Adams, 3 months ago

Browse source code at

Authors: Dean Adams [aut, cre] , Michael Collyer [aut] , Antigoni Kaliontzopoulou [aut] , Erica Baken [aut]

Documentation:   PDF Manual  

Task views: Phylogenetics, Especially Comparative Methods

GPL (>= 2) license

Imports graphics, grDevices, stats, utils, jpeg, ape, parallel, ggplot2

Depends on RRPP, rgl, Matrix

Suggests knitr, rmarkdown, testthat, dplyr

Imported by Evomorph, LOST, Momocs, RPS, SoundShape, patternize.

Suggested by RRphylo, ShapeRotator, prWarp, vcvComp.

See at CRAN