Search code examples
rggplot2geom-bar

Change order of filling variable on a ggplot geom_bar


I have a barplot which I changed the order of samples "BB" "AA". They are filled by condition location.

How can I change the order of the variable filling of the legend so the bars show as Washington-Mongolia-Egypt? (ie: the black column (Egypt) would be on the right, then Mongolia, then the white one (Washington) would be on the left).

sample <- c("AA", "AA", "AA", "BB", "BB", "BB")
location<- c("Washington", "Mongolia", "Egypt", "Washington", "Mongolia", "Egypt" )
value <- c(0.03, 0.06, 0.02, 0.0051, 0.0082, 0.003)
data <- data.frame(sample, location, value)


ggplot(data, aes(fill=location, y=value, x=sample)) + 
    geom_bar(position="dodge", stat="identity", color="black")+
theme_classic()+
 scale_fill_grey() +
  scale_x_discrete(limits=c("BB", "AA"))

enter image description here


Solution

  • You can use position_dodge2 with the argument reverse = TRUE in geom_col (which is equivalent to geom_bar(stat = "identity")).

    I also use guides(fill = guide_legend(reverse = TRUE)) to reverse legend labeling and match the order of bars

    library(ggplot2) 
    
    ggplot(data, aes(fill=location, y=value, x=sample)) + 
      geom_col(position = position_dodge2(reverse = TRUE) color="black")+
      theme_classic()+
      scale_fill_grey() +
      scale_x_discrete(limits=c("BB", "AA"))+
      guides(fill = guide_legend(reverse = TRUE))
    

    enter image description here


    EDIT: Adding geom_errobar using position_dodge2

    As documented in this discussion (https://github.com/tidyverse/ggplot2/issues/2251), when using position_dodge2 fro geom_col, if you want to add geom_errorbar, you need to play with padding argument:

    sample <- c("AA", "AA", "AA", "BB", "BB", "BB")
    location<- c("Washington", "Mongolia", "Egypt", "Washington", "Mongolia", "Egypt" )
    value <- c(0.03, 0.06, 0.02, 0.0051, 0.0082, 0.003)
    sd <- c(0.003, 0.0012, 0.0015, 0.00025, 0.0002, 0.0001) 
    data <- data.frame(sample, location, value, sd)
    
    library(ggplot2)
    
    ggplot(data, aes(fill=location, y=value, x=sample)) + 
      geom_bar(position = position_dodge2(reverse = TRUE), stat="identity", color="black")+
      theme_classic()+
      scale_fill_grey() +
      scale_x_discrete(limits=c("BB", "AA"))+
      guides(fill = guide_legend(reverse = TRUE))+
      geom_errorbar(aes(ymin = value-sd, ymax = value+sd), 
                    position = position_dodge2(reverse = TRUE, padding = 0.6, width = 0.5))
    

    enter image description here