Reputation: 827
I would like to plot a chart with dual Y, both are bar plot with ggplot2, and both bar with its own error bar and label, the following code fails. The bars overlaped, and the labels can not be displayed.
df<- structure(list(dose = structure(1:3, .Label = c("0.5", "1", "2"
), class = "factor"), mean1 = c(13.23, 22.7, 26.06), sd1 = c(0.1,
0.2, 0.3), label = c("a", "b", "c"), mean2 = c(7.98, 16.77, 26.14
), sd2 = c(0.01, 0.2, 0.3), label2 = c("a", "b", "c")), row.names = c(NA,
-3L), class = "data.frame")
ggplot(df,aes(x = dose, fill = dose))+
geom_bar(aes(y = mean1), position = 'dodge', stat="identity", width=.4) +
geom_bar(aes(y = mean2/5), position = 'dodge', stat="identity", width=.4)+
scale_y_continuous(sec.axis = sec_axis(~. *5, name = "mean2"))+
geom_errorbar(aes(ymin = mean1, ymax = mean1 + sd1), width=.07,
position=position_dodge(0.4)) +
geom_errorbar(aes(ymin = mean2, ymax = mean2 + sd2), width=.07,
position=position_dodge(0.4))
geom_text(aes(y =mean1 + sd1, label = label1),vjust = -0.5, position=position_dodge(0.4))
geom_text(aes(y =mean2 + sd2, label = label2,),vjust = -0.5, position=position_dodge(0.4))
Upvotes: 0
Views: 47
Reputation: 8110
Is this what you are looking for? You just need to restructure your data so that it can be dodged by group.
bind_rows(
df |>
select(dose, label, mean = mean1, sd = sd1) |>
mutate(group = 1),
df |>
select(dose, label, mean = mean2, sd = sd2) |>
mutate(group = 2,
mean = mean/5)
) |>
ggplot(aes(x = dose, fill = dose, group = group))+
geom_bar(aes(y = mean), position = 'dodge', stat="identity", width=.4)+
geom_errorbar(aes(ymin = mean, ymax = mean + sd), width=.07,
position=position_dodge(0.4)) +
geom_text(aes(y =mean + sd, label = label),vjust = -0.5, position=position_dodge(0.4))+
scale_y_continuous(sec.axis = sec_axis(~. *5, name = "mean2"))
Upvotes: 1