Search code examples
rggplot2tidyverseerrorbar

Faulty positions of error bars in bar chart


It seems like some of my error bars were right below the bars themselves, instead of ± from the mean. Would appreciate it if there's any advice on this.

My plot Image1

My script

psbs <- read_csv("psbs.csv")
spsbs<-summarySE(data=psbs, measurevar="fv", groupvars=c("Line", "genotype"))

P1<- ggplot(data=psbs, mapping = aes(x = factor(genotype), y = fv, fill= Line))+
  geom_bar(stat = "identity", position = "dodge")+
  geom_errorbar(data=spsbs, aes(ymin=fv-se, ymax=fv+se), width=.35, position=position_dodge(width= 0.9))+
  theme_bw()+
  theme(text = element_text(size = 13))+
  theme(axis.text.x=element_blank())+
  facet_wrap(~genotype,scales="free")+
  ylim(0,1.0)+
  labs(x = element_blank(), y="Fv/Fm", fill= "Line")

My data frame

data.frame(psbs)
   id genotype Line   fv
1   1     PsbS L1.1 0.82
2   2     PsbS L1.1 0.82
3   3     PsbS L1.1 0.82
4   4     PsbS L1.2 0.82
5   5     PsbS L1.2 0.82
6   6     PsbS L1.2 0.82
7   7     PsbS L1.3 0.82
8   8     PsbS L1.3 0.82
9   9     PsbS L1.3 0.83
10 10     PsbS L1.4 0.82
11 11     PsbS L1.4 0.82
12 12     PsbS L1.4 0.82
13 13     PsbS L1.5 0.82
14 14     PsbS L1.5 0.83
15 15     PsbS L1.5 0.82
16 16     PsbS L1.6 0.82
17 17     PsbS L1.6 0.82
18 18     PsbS L1.6 0.83
19 19     PsbS L1.7 0.82
20 20     PsbS L1.7 0.82
21 21     PsbS L1.7 0.82
22 22     PsbS L1.8 0.83
23 23     PsbS L1.8 0.82
24 24     PsbS L1.8 0.82
25 25     PsbS L1.9 0.82
26 26     PsbS L1.9 0.83
27 27     PsbS L1.9 0.82

Solution

  • The issue is that you have multiple values or obs. per Line in your psbs dataframe. When using geom_bar(stat = "identity", position = "dodge") you are plotting each of these values on top each other and hence the "bar"s reflect the maximum value per Line. If you want to show the mean then IMHO. you could simply use the spsbs dataframe for the bars too which already contains the mean value per Line.

    library(ggplot2)
    library(Rmisc)
    
    spsbs <- summarySE(data = psbs, measurevar = "fv", groupvars = c("Line", "genotype"))
    
    ggplot(data = spsbs, mapping = aes(x = factor(genotype), y = fv, fill = Line)) +
      geom_col(position = "dodge") +
      geom_errorbar(aes(ymin = fv - se, ymax = fv + se), width = .35, position = position_dodge(width = 0.9)) +
      theme_bw() +
      theme(text = element_text(size = 13)) +
      theme(axis.text.x = element_blank()) +
      facet_wrap(~genotype, scales = "free") +
      ylim(0, 1.0) +
      labs(x = element_blank(), y = "Fv/Fm", fill = "Line")
    

    enter image description here

    DATA

    structure(list(id = 1:27, genotype = c("PsbS", "PsbS", "PsbS", 
    "PsbS", "PsbS", "PsbS", "PsbS", "PsbS", "PsbS", "PsbS", "PsbS", 
    "PsbS", "PsbS", "PsbS", "PsbS", "PsbS", "PsbS", "PsbS", "PsbS", 
    "PsbS", "PsbS", "PsbS", "PsbS", "PsbS", "PsbS", "PsbS", "PsbS"
    ), Line = c("L1.1", "L1.1", "L1.1", "L1.2", "L1.2", "L1.2", "L1.3", 
    "L1.3", "L1.3", "L1.4", "L1.4", "L1.4", "L1.5", "L1.5", "L1.5", 
    "L1.6", "L1.6", "L1.6", "L1.7", "L1.7", "L1.7", "L1.8", "L1.8", 
    "L1.8", "L1.9", "L1.9", "L1.9"), fv = c(0.82, 0.82, 0.82, 0.82, 
    0.82, 0.82, 0.82, 0.82, 0.83, 0.82, 0.82, 0.82, 0.82, 0.83, 0.82, 
    0.82, 0.82, 0.83, 0.82, 0.82, 0.82, 0.83, 0.82, 0.82, 0.82, 0.83, 
    0.82)), class = "data.frame", row.names = c("1", "2", "3", "4", 
    "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", 
    "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", 
    "27"))