0
votes

I am creating a simple stacked geom_bar with two groups, and with geom_errorbar. I have reversed the order of the two groups, but the order of the error bars will not follow.

I have tried by changed the order of the groups as factors: - fill = forcats::fct_rev(levels) And also changing the order of the groups in the dataframe: - arrange(df, desc(levels))

ggplot(subset(c, frac %in% c("DOC", "POC")), aes(x=Station.name, y=Ave,
                                                     fill=frac))+
      geom_bar(stat="identity", width=0.6)+
      scale_fill_manual(values = c("lightskyblue", "dodgerblue2"))+
      geom_errorbar(aes(x=Station.name, ymin=Ave-sd, ymax=Ave+sd),
                  width=.2,size=0.2)

For every attempt, the bars in the plot successfully change their order, but the error bars never follow.... I would like to change the order so that the group with the highest value (dark blue) is at the bottom and the group with the lowest value (light blue) is at the top. The two figures illustrate my to types of outcome. (The issue is related to the position of the error bars and not the value).

I would like to have the opposite of this:

image 1

Why won't the order of the error bars follow the order of the bars?

image 2

Here is a subset of the dataframe:

structure(list(Station.name = structure(c(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 11L, 12L, 13L, 14L, 15L, 16L, 17L, 18L, 19L, 20L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 11L, 12L, 13L, 14L, 15L, 16L, 17L, 18L, 19L, 20L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 11L, 12L, 13L, 14L, 15L, 16L, 17L, 18L, 19L, 20L), .Label = c("a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t"), class = "factor"), Ave = c(3.525, 3.025, 1.45, 2.975, 1.9425, 3.066666667, 1.68, 1.9, 2.575, 4, 4.7, 5.566666667, 2.4, 3.05, 2.4, 5.325, 2.825, 1.825, 1.2075, 1.165, 0.1, 0.025, 0.05, 1.11e-16, 0.055, 0, 0.0525, 0, 0.05, 0.05, 0.125, 0.266666667, 0.075, -0.125, 0.125, 0.075, 0.15, 0.025, 0.0725, -0.0075, 3.425, 3, 1.4, 2.975, 1.8875, 3.066666667, 1.6275, 1.9, 2.525, 3.95, 4.575, 5.3, 2.325, 3.175, 2.275, 5.25, 2.675, 1.8, 1.135, 1.1725 ), sd = c(0.763216876, 0.170782513, 0.2081666, 0.457347424, 0.789023658, 0.776745347, 1.239462249, 0.816496581, 0.287228132, 1.699019325, 2.24053565, 1.77857621, 0.496655481, 0.873689495, 0.081649658, 0.994568583, 1.129527925, 0.713559154, 0.344806709, 0.246779254, 0.163299316, 0.05, 0.1, 0.141421356, 0.052599113, 0.1, 0.098446263, 0, 0.057735027, 0.057735027, 0.125830574, 0.152752523, 0.05, 0.206155281, 0.189296945, 0.05, 0.191485422, 0.125830574, 0.037749172, 0.069940451, 0.62915287, 0.141421356, 0.21602469, 0.49244289, 0.755397246, 0.757187779, 1.14441761, 0.816496581, 0.320156212, 1.755942292, 2.136000936, 1.637070554, 0.518812747, 0.81394103, 0.206155281, 1.034408043, 1.209338662, 0.594418483, 0.318904374, 0.278732249), frac = structure(c(3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), .Label = c("DOC", "POC", "TOC"), class = "factor")), class = "data.frame", row.names = c(NA, -60L))

1
For the error bars you are plotting (Ave-sd) & (Ave+sd) just because the small bars are on top, doesn't mean their values have change, therefore the error bars position aren't changing with the change in plot order. In order to receive a solution, please edit the question and provide sample data for people to test.Dave2e
Thank you for your comment @DaveT I have tried to include a subset of my dataframe, is it the correct way of doing it? I am not sure if i understood your comment with regards to editing my question (?).cathrine

1 Answers

0
votes

Here is solution, but the stacked solution does provide a very meaningful presentation since the error bars overlap with each other. I recommend using the dodged chart for a clearer presentation of the data.

To create the stack chart properly the "frac" column and the factor levels needed to be sorted into the desired plotting order.
See comments in code for details.

df<-structure(list(Station.name = structure(c(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 11L, 12L, 13L, 14L, 15L, 16L, 17L, 18L, 19L, 20L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 11L, 12L, 13L, 14L, 15L, 16L, 17L, 18L, 19L, 20L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 11L, 12L, 13L, 14L, 15L, 16L, 17L, 18L, 19L, 20L), .Label = c("a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t"), class = "factor"), Ave = c(3.525, 3.025, 1.45, 2.975, 1.9425, 3.066666667, 1.68, 1.9, 2.575, 4, 4.7, 5.566666667, 2.4, 3.05, 2.4, 5.325, 2.825, 1.825, 1.2075, 1.165, 0.1, 0.025, 0.05, 1.11e-16, 0.055, 0, 0.0525, 0, 0.05, 0.05, 0.125, 0.266666667, 0.075, -0.125, 0.125, 0.075, 0.15, 0.025, 0.0725, -0.0075, 3.425, 3, 1.4, 2.975, 1.8875, 3.066666667, 1.6275, 1.9, 2.525, 3.95, 4.575, 5.3, 2.325, 3.175, 2.275, 5.25, 2.675, 1.8, 1.135, 1.1725 ), sd = c(0.763216876, 0.170782513, 0.2081666, 0.457347424, 0.789023658, 0.776745347, 1.239462249, 0.816496581, 0.287228132, 1.699019325, 2.24053565, 1.77857621, 0.496655481, 0.873689495, 0.081649658, 0.994568583, 1.129527925, 0.713559154, 0.344806709, 0.246779254, 0.163299316, 0.05, 0.1, 0.141421356, 0.052599113, 0.1, 0.098446263, 0, 0.057735027, 0.057735027, 0.125830574, 0.152752523, 0.05, 0.206155281, 0.189296945, 0.05, 0.191485422, 0.125830574, 0.037749172, 0.069940451, 0.62915287, 0.141421356, 0.21602469, 0.49244289, 0.755397246, 0.757187779, 1.14441761, 0.816496581, 0.320156212, 1.755942292, 2.136000936, 1.637070554, 0.518812747, 0.81394103, 0.206155281, 1.034408043, 1.209338662, 0.594418483, 0.318904374, 0.278732249), frac = structure(c(3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), .Label = c("DOC", "POC", "TOC"), class = "factor")), class = "data.frame", row.names = c(NA, -60L))

library(ggplot2)
library(dplyr)
library(forcats)

#dodge plot
ggplot(subset(df, frac %in% c("DOC", "POC")), 
       aes(x=Station.name, y=Ave, fill=frac))+
  geom_col(width=0.6, position = "dodge")+
  scale_fill_manual(values = c("lightskyblue", "dodgerblue2"))+
  geom_errorbar(aes(x=Station.name, ymin=Ave-sd, ymax=Ave+sd),
                width=.2,size=0.2, position = position_dodge(0.5))

enter image description here

#to create the stacked chart with the error bars in the proper location
#reverse the order of the factor and resort the data frame to match the new factor order
df$frac<-fct_rev(df$frac)
df<-df[rev(order(df$frac)),]

#calculate the limits based on the subset
df2<-df %>% filter(frac=="DOC" | frac=="POC") %>% 
  group_by(Station.name) %>% 
  mutate(ymin=cumsum(Ave)-sd, ymax=cumsum(Ave)+sd)

#plot
ggplot(df2, aes(x=Station.name, y=Ave, fill=frac))+
  geom_col(width=0.6)+
  scale_fill_manual(values = c("lightskyblue", "dodgerblue2"))+
  geom_errorbar(aes(x=Station.name, ymin=ymin, ymax=ymax),
                width=.2,size=0.2)

enter image description here