Here is one dataset
df=data.frame(
cultivar = rep(c("CV1", "CV2"), each = 8L),
part = rep(rep(c("DW1", "DW2"), 2), each = 4L),
Light = rep(rep(c("Light1", "Light2"), 4), each = 2L),
Treatment = rep(c("Treatment 1", "Treatment 2"), 8),
DW_Mean = c(69.2825, 94.82, 57.8025, 90.7225, 26.6975, 37.3, 21.73, 28.3525, 58.825,
79.45, 45.3225, 67.2425, 24.78, 32.2425, 16.8475, 24.9825
),
DW_se = c(7.3890441138666, 12.3060777666972, 4.7905851678057, 5.91931355113637,
5.10530830769961, 2.13571221531991, 1.87420205243014, 0.906838601957373,
3.60502773914432, 7.59180918270913, 2.066044429177, 4.76078840634616,
2.56271990926307, 1.23644904868741, 1.94433096891107, 2.04306295791393))
and I want to put error bars at each stacked bar. So I used this code.
library(dplyr)
library(ggplot2)
dplyr::mutate(df, .by=cultivar, cume_y=cumsum(DW_Mean)) |>
ggplot(aes(x=cultivar, y=DW_Mean, fill=part)) +
geom_bar(stat="identity", position=position_stack(reverse=T), width=0.7, size=1) +
geom_errorbar(aes(ymin=cume_y-DW_se, ymax=cume_y+DW_se),
position="identity", width=0.3) +
scale_fill_manual(values = c("coral4", "grey45")) +
scale_y_continuous(breaks = seq(0, 200, 50), limits = c(0, 200)) +
facet_grid(~ Light ~ Treatment, scales = "free") +
annotate("segment", x = 1, xend = 2, y = Inf, yend = Inf, color = "black", lwd = 1) +
annotate("segment", y = 50, yend = 150, x = Inf, xend = Inf, color = "black", lwd = 1) +
theme_classic(base_size = 18, base_family = "serif") +
theme(legend.position = c(0.4, 0.9),
legend.title = element_blank(),
axis.line = element_line(linewidth = 0.5, colour = "black"),
strip.background = element_rect(color = "white", linewidth = 0.5, linetype = "solid"))
Now, the error bars are misplaced. If I filter each variable (i.e., only Treatment 1 and Light 1) and create the stacked bar, I can place the error bars at the exact location of the stacked bar. However, when I use facet_grid()
, the error bars are misplaced.
Could you please let me know how to solve this problem?
Thanks,
I think your code for geom_bar()
and geom_errorbar()
should be working fine. However, the code for generating cume_y
variable might be problematic. I replace .by=cultivar
with .by = c(Treatment, Light, cultivar)
as in the following
library(dplyr)
library(ggplot2)
df |>
mutate(.by = c(Treatment, Light, cultivar), cume_y = cumsum(DW_Mean)) |>
ggplot(aes(x = cultivar, y = DW_Mean, fill = part)) +
geom_bar(stat = "identity", position = position_stack(reverse = T), width = 0.7, size = 1) +
geom_errorbar(aes(ymin = cume_y - DW_se, ymax = cume_y + DW_se),
position = "identity", width = 0.3
) +
scale_fill_manual(values = c("coral4", "grey45")) +
scale_y_continuous(breaks = seq(0, 200, 50), limits = c(0, 200)) +
facet_grid(~Light ~ Treatment, scales = "free") +
annotate("segment", x = 1, xend = 2, y = Inf, yend = Inf, color = "black", lwd = 1) +
annotate("segment", y = 50, yend = 150, x = Inf, xend = Inf, color = "black", lwd = 1) +
theme_classic(base_size = 18, base_family = "serif") +
theme(
legend.position = c(0.4, 0.9),
legend.title = element_blank(),
axis.line = element_line(linewidth = 0.5, colour = "black"),
strip.background = element_rect(color = "white", linewidth = 0.5, linetype = "solid")
)