Reinventing the wheel for ordination biplots with ggplot2

I’ll be the first to admit that the topic of plotting ordination results using ggplot2 has been visited many times over. As is my typical fashion, I started creating a package for this purpose without completely searching for existing solutions. Specifically, the ggbiplot and factoextra packages already provide almost complete coverage of plotting results from multivariate and ordination analyses in R. Being the stubborn individual, I couldn’t give up on my own package so I started exploring ways to improve some of the functionality of biplot methods in these existing packages. For example, ggbiplot and factoextra work almost exclusively with results from principal components analysis, whereas numerous other multivariate analyses can be visualized using the biplot approach. I started to write methods to create biplots for some of the more common ordination techniques, in addition to all of the functions I could find in R that conduct PCA. This exercise became very boring very quickly so I stopped adding methods after the first eight or so. That being said, I present this blog as a sinking ship that was doomed from the beginning, but I’m also hopeful that these functions can be built on by others more ambitious than myself.

The process of adding methods to a default biplot function in ggplot was pretty simple and not the least bit interesting. The default ggpord biplot function (see here) is very similar to the default biplot function from the stats base package. Only two inputs are used, the first being a two column matrix of the observation scores for each axis in the biplot and the second being a two column matrix of the variable scores for each axis. Adding S3 methods to the generic function required extracting the relevant elements from each model object and then passing them to the default function. Easy as pie but boring as hell.

I’ll repeat myself again. This package adds nothing new to the functionality already provided by ggbiplot and factoextra. However, I like to think that I contributed at least a little bit by adding more methods to the biplot function. On top of that, I’m also naively hopeful that others will be inspired to fork my package and add methods. Here you can view the raw code for the ggord default function and all methods added to that function. Adding more methods is straightforward, but I personally don’t have any interest in doing this myself. So who wants to help??

Visit the package repo here or install the package as follows.


Available methods and examples for each are shown below. These plots can also be reproduced from the examples in the ggord help file.

##  [1] ggord.acm       ggord.coa      ggord.default 
##  [5] ggord.lda      ggord.mca      ggord.MCA      ggord.metaMDS 
##  [9] ggord.pca      ggord.PCA      ggord.prcomp   ggord.princomp
# principal components analysis with the iris data set
# prcomp
ord <- prcomp(iris[, 1:4])

p <- ggord(ord, iris$Species)

p + scale_colour_manual('Species', values = c('purple', 'orange', 'blue'))

p + theme_classic()

p + theme(legend.position = 'top')

p + scale_x_continuous(limits = c(-2, 2))

# principal components analysis with the iris dataset
# princomp
ord <- princomp(iris[, 1:4])

ggord(ord, iris$Species)

# principal components analysis with the iris dataset

ord <- PCA(iris[, 1:4], graph = FALSE)

ggord(ord, iris$Species)

# principal components analysis with the iris dataset
# dudi.pca

ord <- dudi.pca(iris[, 1:4], scannf = FALSE, nf = 4)

ggord(ord, iris$Species)

# multiple correspondence analysis with the tea dataset
tea <- tea[, c('Tea', 'sugar', 'price', 'age_Q', 'sex')]

ord <- MCA(tea[, -1], graph = FALSE)

ggord(ord, tea$Tea)

# multiple correspondence analysis with the tea dataset
# mca

ord <- mca(tea[, -1])

ggord(ord, tea$Tea)

# multiple correspondence analysis with the tea dataset
# acm
ord <- dudi.acm(tea[, -1], scannf = FALSE)

ggord(ord, tea$Tea)

# nonmetric multidimensional scaling with the iris dataset
# metaMDS
ord <- metaMDS(iris[, 1:4])

ggord(ord, iris$Species)

# linear discriminant analysis
# example from lda in MASS package
ord <- lda(Species ~ ., iris, prior = rep(1, 3)/3)

ggord(ord, iris$Species)

# correspondence analysis
# dudi.coa
ord <- dudi.coa(iris[, 1:4], scannf = FALSE, nf = 4)

ggord(ord, iris$Species)

# correspondence analysis
# ca
ord <- ca(iris[, 1:4])

ggord(ord, iris$Species)



13 thoughts on “Reinventing the wheel for ordination biplots with ggplot2

  1. PCA - FA - MDS | Pearltrees

  2. Distilled News | Data Analytics & R

  3. Adding other methods like you did is actually very useful. The package can be used as a ‘map’ to all these PCA/MCA/etc. functions lying around.

    Have you taken a look at this package and that package? Perhaps you could also use autoplot function.

    • Thanks, I hope that at least a few people find these added methods useful… and that even some might contribute! I haven’t seen either of the packages you referenced but the autoplot function looks very useful. I’ll keep it in mind for future updates.

  4. Ha that’s really useful! I was just making the same thing when I discovered this. Still a fair few methods that could be included – nipals, principal, factanal,, PLS, pcaridge, prm, pcaRes, bfa, rda, NMDS… The ordination methods in the vegan package could perhaps be most useful still. Did you also see the package UBbipl of the book “Understanding biplots” and the book “Biplots in practice” is also good to check out (can send you the pdf if you wouldn’t have them). Convex hull could be nice alternative for confidence ellipses, or confidence bags, perhaps filled with semi-transp colours as opposed to outlines. Are you planning to send this to CRAN?

    • Hi Tom,

      Thanks for reading and I’m glad you found the package useful. I know the package was missing several methods for other ordination functions in R… and I was hoping that others would fork and contribute to the repo on GitHub. So far, no progress has been made but I’m still hopeful! I don’t have any plans to submit this to CRAN, unless I make significant progress on at least making this inclusive to a majority of the ordination functions in R. Some of the minor suggestions you make would be pretty straightforward to add (convex hull, confidence bags, etc.), so you should put in a request on the issues page if you’d like them included in the develoment repo.


    • Yep, you can do this with the arguments as follows:

      ord <- prcomp(iris[, 1:4])
      ggord(ord, iris$Species, vec_ext = 0, txt = NULL, arrow = 0)

      This removes both the vectors and the labels. I’d have to change the function to manipulate both, which wouldn’t be hard. You can put in an issue request on the GitHub page if you want this feature.

      • Thanks! I have a final question (hopefully!!!) Is it possible to change the vector text labels in the LDA, to make them smaller? I can’t figure out whether I need to use MASS or ggplot2 to do so.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s