Search code examples
rggplot2vegan

ggplot2 version of shepard plot, i.e. vegan::stressplot()?


There seems to be quite a bit of information for plotting NMDS outputs (i.e. NMDS1 vs NMDS1) using ggplot2 however I cannot find a way to plot the vegan::stressplot() (shepard's plot) using ggplot2.

Is there a way to produce a ggplot2 version of a metaMDS output?

Reproducible code

library(vegan)

set.seed(2)

community_matrix = matrix(
  sample(1:100,300,replace=T),nrow=10,
  dimnames=list(paste("community",1:10,sep=""),paste("sp",1:30,sep="")))

example_NMDS=metaMDS(community_matrix, k=2) 

stressplot(example_NMDS)

Created on 2021-09-17 by the reprex package (v2.0.1)


Solution

  • Here's a workaround to plot a very similar plot using ggplot2.The trick was to get the structure of the stressplot(example_NMDS) and extract the data stored in that object. I used the tidyverse package that includes ggplot and other packages such as tidyr that contains the pivot_longer function.

    library(vegan)
    library(tidyverse)
    
    # Analyze the structure of the stressplot
    # Notice there's an x, y and yf list
    str(stressplot(example_NMDS))
    
    # Create a tibble that contains the data from stressplot
    df <- tibble(x = stressplot(example_NMDS)$x,
           y = stressplot(example_NMDS)$y,
           yf = stressplot(example_NMDS)$yf) %>%
      # Change data to long format
      pivot_longer(cols = c(y, yf),
                   names_to = "var")
    
    # Create plot
    df %>%
      ggplot(aes(x = x,
                 y = value)) +
      # Add points just for y values
      geom_point(data = df %>%
                   filter(var == "y")) +
      # Add line just for yf values
      geom_step(data = df %>%
                  filter(var == "yf"),
                col = "red",
                direction = "vh") +
      # Change axis labels
      labs(x = "Observed Dissimilarity", y = "Ordination Distance") +
      # Add bw theme
      theme_bw()
    

    stressplot