Search code examples
rggplot2pcavegan

Customizing a vegan pca plot with ggplot2


I'm trying to make a custom plot of some vegan rda results in ggplot2. I'm essentially modifying directions as seen in Plotting RDA (vegan) in ggplot, so that I am using shape and color labels to convey some information about the sample points.

I set up a pca analysis with vegan as follows

library(vegan)
library(dplyr)
library(tibble)
library(ggplot2)
cbPalette <- c("#000000", "#E69F00", "#56B4E9", "#009E73",  "#0072B2", "#D55E00", "#CC79A7", "#F0E442")
data(dune)
data(dune.env)
dune.pca <- rda(dune)
uscores <- data.frame(dune.pca$CA$u)
uscores1 <- inner_join(rownames_to_column(dune.env), rownames_to_column(data.frame(uscores)), type = "right", by = "rowname")
vscores <- data.frame(dune.pca$CA$v)

I can make a simple biplot

 biplot(dune.pca)

test biplot

Now, lets say I want to know more about the management conditions to which these different samples were subject. I'll color and shape code them and plot with ggplot.

p1 <- ggplot(uscores1, aes(x = PC1, y = PC2, col = Management,
                         shape = Management)) + 
geom_point() +
scale_color_manual(values=cbPalette) +
scale_fill_manual(values=cbPalette) +
scale_shape_manual(values = c(21:25)) +
theme_bw() +
theme(strip.text.y = element_text(angle = 0))
p1

test points

Next, I'd really like to add some biplot arrows that show us the axes corresponding to species abundance. I can use ggplot to plot just those arrows as follows:

p2 <- ggplot() +  geom_text(data = vscores, aes(x = PC1, y = PC2, label = rownames(vscores)), col = 'red') +
geom_segment(data = vscores, aes(x = 0, y = 0, xend = PC1, yend = PC2), arrow=arrow(length=unit(0.2,"cm")),
            alpha = 0.75, color = 'darkred')
p2

test arrows

What I'd really like to do though, is get those arrows and points on the same plot. Currently this is the code that I am trying to use:

p3 <- p1 + geom_text(data = vscores, aes(x = PC1, y = PC2, label = rownames(vscores)), col = 'red') +
geom_segment(data = vscores, aes(x = 0, y = 0, xend = PC1, yend = PC2), arrow=arrow(length=unit(0.2,"cm")),
            alpha = 0.75, color = 'darkred')
p3

To my annoyance, this yields only a blank plot (empty window, no error messages). Clearly I am missing something or scaling something incorrectly. Any suggestions about how I can best superimpose the last two plots?


Solution

  • Try:

    library(cowplot) #not needed I just had it attached while answering the question hence the theme.
    library(ggplot2)
    
    ggplot(uscores1) + 
          geom_point(aes(x = PC1, y = PC2, col = Management,
                         shape = Management)) +
          scale_color_manual(values=cbPalette) +
          scale_fill_manual(values=cbPalette) +
          scale_shape_manual(values = c(21:25)) +
          geom_text(data = vscores, aes(x = PC1, y = PC2, label = rownames(vscores)), col = 'red') +
          geom_segment(data = vscores, aes(x = 0, y = 0, xend = PC1, yend = PC2), arrow=arrow(length=unit(0.2,"cm")),
                       alpha = 0.75, color = 'darkred')+
          theme_bw() +
          theme(strip.text.y = element_text(angle = 0))
    

    enter image description here

    The p1 plot was passing col and shape variable Management to geom_text/geom_segment since they were not defined there but there is no Management column in data = vscores. At least I think so based on the error:

    `Error in eval(expr, envir, enclos) : object 'Management' not found`