rggplot2dplyrbiplot

Plot means and sd error bars for both x and y


I would like to produce a scatterplot using ggplot that shows the means and sds of d13C on the x-axis and d15N on the y-axis for each Genus in my study. I can do the calculations and get the means and error bars in each dimension separately but I cannot not show them together. Would be great to code the points by Class.

These types of plots are very common in isotope studies so I was surprised not to find the code for it.

I tried a few different things but this is the closest I was able to get:

N_mean_std <- NescoA %>%
  group_by(Genus) %>%
  summarise_at(vars(d15N), list(meanN=mean, sdN=sd)) %>% 
  as.data.frame() 

C_mean_std <- NescoA %>%
  group_by(Genus) %>%
  summarise_at(vars(d13C), list(meanC=mean, sdC=sd)) %>% 
  as.data.frame()

#view results
N_mean_std
C_mean_std

so far so good but

ggplot(N_mean_std , aes(x=Genus, y=meanN)) + 
  geom_errorbar(aes(ymin=meanN-sdN, ymax=meanN+sdN), width=.3) +
  geom_point(size=2) +
  geom_errorbar(aes(ymin=meanC-sdC, ymax=meanC+sdC), width=0.3)

This doesn't work because the ggplot only calls up the nitrogen data. How do I merge these two together on a single graph?

Here are the data

structure(list(Class = c("Aves", "Arachnida", "Arachnida", "Arachnida", 
"Diplopoda", "Insecta", "Insecta", "Insecta", "Insecta", "Insecta", 
"Insecta", "Insecta", "Insecta", "Insecta", "Insecta", "Insecta", 
"Insecta", "Insecta", "Insecta", "Insecta"), Genus = c("Melospiza", 
"(Lycosidae)", NA, NA, "Cambala", NA, "Oulema", "Oulema", NA, 
NA, "(Scolytidae)", NA, "Forficula", NA, NA, NA, NA, "Anasa", 
NA, NA), site.code = c("NESCO_A", "NESCO_A", "NESCO_A", "NESCO_A", 
"NESCO_A", "NESCO_A", "NESCO_A", "NESCO_A", "NESCO_A", "NESCO_A", 
"NESCO_A", "NESCO_A", "NESCO_A", "NESCO_A", "NESCO_A", "NESCO_A", 
"NESCO_A", "NESCO_A", "NESCO_A", "NESCO_A"), d13C = c(-24.61, 
-25.07, -25.27, -22.84, -19.95, -28.04, -19.57, -24.3, -20.16, 
-18.99, -18.54, -27.66, -24.75, -30.18, -28.59, -19.78, -14.52, 
-26.18, -25.02, -26.32), d15N = c(4.39, 4.32, 6.27, 4.2, 2.31, 
1.22, -0.27, 0.91, 0.08, 4.32, 2.46, -0.63, -0.9, 7.46, 6.15, 
1.2, 1.13, 0.94, 0.23, 4.6)), row.names = c(NA, 20L), class = "data.frame")

Solution

  • This should set you on the right track:

    First, I think there's no reason to separate the summarized data into two dataframes:

    df_summary <- df %>% group_by(Class,Genus) %>%
      summarize(
        d15N_mean = mean(d15N),
        d13C_mean = mean(d13C),
        d15N_sd = sd(d15N),
        d13C_sd = sd(d13C)
      )
    

    Then you can easily plot your points with the errorbars and group it any way you want. I chose to color-code the genus and facet wrap by class:

    ggplot(data = df_summary, aes(x = d13C_mean, y = d15N_mean, color = Genus)) + geom_point() +
      geom_errorbar(aes(ymin=d15N_mean-d15N_sd,ymax=d15N_mean+d15N_sd)) +
      geom_errorbarh(aes(xmin=d13C_mean-d13C_sd,xmax=d13C_mean+d13C_sd)) +
      facet_wrap(~Class)
    

    enter image description here

    On second thought, faccet-wrapping doesn't make too much sense because each genus can only be in once class, so maybe use color for the genus and shape for the class:

    ggplot(data = df_summary, aes(
      x = d13C_mean,
      y = d15N_mean,
      color = Genus,
      shape = Class)) + 
      geom_point(stroke=2) +
      geom_errorbar(aes(ymin = d15N_mean - d15N_sd, ymax = d15N_mean + d15N_sd)) +
      geom_errorbarh(aes(xmin = d13C_mean - d13C_sd, xmax = d13C_mean + d13C_sd))
    

    enter image description here

    I hope I was able to help you!