DCA : Labelling points with autoplot or ggplot2

2k views Asked by At

I find very difficult to put labels for sites with a DCA in a autoplot or ggplot.
I also want to differentiate the points on the autoplot/ggplot according to their groups.
This is the data and the code I used and it went well until the command for autoplot/ggplot:

library(vegan)
data(dune)
d <- vegdist(dune)
csin <- hclust(d, method = "single")
cl <- cutree(csin, 3)
dune.dca <- decorana(dune)
autoplot(dune.dca)

This is the autoplot obtained:

dca_autoplot

I am using simple coding and I tried these codes but they didn't led me anywhere:

autoplot(dune.dca, label.size = 3, data = dune, colour = cl)
ggplot(dune.dca(x=DCA1, y=DCA2,colour=cl))
ggplot(dune.dca, display = ‘site’, pch = 16, col = cl)
ggrepel::geom_text_repel(aes(dune.dca))

If anyone has a simple suggestion, it could be great.

1

There are 1 answers

3
Oliver On BEST ANSWER

With the added information (package) I was able to go and dig a bit deeper.

The problem is (in short) that autoplot.decorana adds the data to the specific layer (either geom_point or geom_text). This is not inherited to other layers, so adding additional layers results in blank pages.

Basically notice that one of the 2 code strings below results in an error, and note the position of the data argument:

# Error: 
ggplot() + 
  geom_point(data = mtcars, mapping = aes_string(x = 'hp', y = 'mpg')) +
  geom_label(aes(x = hp, y = mpg, label = cyl))
# Work:
ggplot(data = mtcars) + 
  geom_point(mapping = aes_string(x = 'hp', y = 'mpg')) +
  geom_label(aes(x = hp, y = mpg, label = cyl))

ggvegan:::autoplot.decorana places data as in the example the returns an error.

I see 2 ways to get around this problem:

  1. Extract the layers data using ggplot_build or layer_data and create an overall or single layer mapping.
  2. Extract the code for generating the data, and create our plot manually (not using autoplot).

I honestly think the second is simpler, as we might have to extract more information to make our data sensible. By looking at the source code of ggvegan:::autoplot.decorana (simply printing it to console by leaving out brackets) we can extract the below code which generates the same data as used in the plot

ggvegan_data <- function(object, axes = c(1, 2), layers = c("species", "sites"), ...){
  obj <- fortify(object, axes = axes, ...)
  obj <- obj[obj$Score %in% layers, , drop = FALSE]
  want <- obj$Score %in% c("species", "sites")
  obj[want, , drop = FALSE]
}

With this we can then generate any plot that we desire, with appropriate mappings rather than layer-individual mappings

dune.plot.data <- ggvegan_data(dune.dca)
p <- ggplot(data = dune.dca, aes(x = DCA1, DCA2, colour = Score)) + 
  geom_point() + 
  geom_text(aes(label = Label), nudge_y = 0.3)
p

Which gives us what I hope is your desired output point+label plot (from code above)