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")
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)
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))
I hope I was able to help you!