Search code examples
rfacetcolumn-widthgeom-col

Rstudio: Adjusting bar width of grouped bar plot in facets


I have a Data set which I am trying to plot as grouped columns in facets, with the columns in equal size.

Data set:

Day=rep(1:6, times=15)

Colour=c("Yellow", "Yellow","Yellow","Yellow","Yellow","Yellow", "Red", "Red","Red","Red","Red","Red", "Green","Green","Green","Green","Green","Green", "Yellow", "Yellow","Yellow","Yellow","Yellow","Yellow", "Red", "Red","Red","Red","Red","Red", "Green","Green","Green","Green","Green","Green", "Blue","Blue","Blue","Blue","Blue","Blue", "Purple","Purple","Purple","Purple","Purple","Purple", "Yellow", "Yellow","Yellow","Yellow","Yellow","Yellow", "Red", "Red","Red","Red","Red","Red", "Green","Green","Green","Green","Green","Green", "Yellow", "Yellow","Yellow","Yellow","Yellow","Yellow", "Red", "Red","Red","Red","Red","Red", "Green","Green","Green","Green","Green","Green", "Yellow", "Yellow","Yellow","Yellow","Yellow","Yellow")

Values=rep(c(9,8,7,6,5,8,7,6,5,4,7,6,5,4,3), times=6)

Fruit=rep(c("CApple", "Banana", "ABlueberry","Mango", "Melon", "Pear"), times = c(18,18,12,18,18,6))

Data <-data.frame(Day, Fruit, Colour, Values) %>%
mutate(unten=Values-0.2, oben=Values+0.2)

My code is:

ForPlot <-  ggplot(Data, aes(Colour, Values), fill=Colour)

design <- theme(strip.background = element_blank(),
                 panel.background = element_blank(),  
                 panel.grid.major = element_blank(),
                 strip.placement = "outside",
                 panel.border=element_blank(),
                 #     axis.line = element_line(colour = "black"),
                 axis.line.x = element_line(colour = "white"),
                 axis.ticks.x=element_blank(),
                 legend.title = element_blank(),
                 # axis.text=element_text(size=8),
                 axis.text.x=element_blank(),
                 axis.title=element_text(size=10),
                 strip.text = element_text(size = 10)) 

  ForPlot+
  geom_hline(yintercept = c(0, 2.5, 5, 7.5, 10), colour= "lightgrey" )+
  geom_col(aes(fill=Colour), 
           position=position_dodge2(preserve="single"))+
  ggtitle("Fruity Colours")+
  ylab("Values") + xlab("Day") +
  facet_wrap(~Fruit,  scales= "free", ncol=3)+
  scale_y_continuous()+
  scale_fill_discrete()+
  geom_text(aes(label = Day), position=position_dodge2(width= 0.9), 
            y=-0.2, size=2.4) +
  geom_errorbar(aes(ymin=pmax(0,unten), ymax=oben), 
                position=position_dodge2())+
  design+
  geom_segment(aes(x=0.4,xend=Inf, y=0, yend=0), color="black")+
  geom_segment(aes(x=0.4,xend=0.4, y=0, yend=Inf), colour="black")

Currently, the bars in the different facets all have different width. I have tried to adjust the problem using "width=" but without success (bars only shrink relative to their current size or I loose my Day labels and errorbars).

Help is appreciated!


Solution

  • Pointing to the useful comment of @aosmith this can help:

    ForPlot+
      geom_hline(yintercept = c(0, 2.5, 5, 7.5, 10), colour= "lightgrey" )+
      geom_col(aes(fill=Colour), 
               position=position_dodge2(preserve="single"))+
      ggtitle("Fruity Colours")+
      ylab("Values") + xlab("Day") +
      facet_grid(.~Fruit,  scales= "free", space = 'free')+
      scale_y_continuous()+
      scale_fill_discrete()+
      geom_text(aes(label = Day), position=position_dodge2(width= 0.9), 
                y=-0.2, size=2.4) +
      geom_errorbar(aes(ymin=pmax(0,unten), ymax=oben), 
                    position=position_dodge2())+
      design+
      geom_segment(aes(x=0.4,xend=Inf, y=0, yend=0), color="black")+
      geom_segment(aes(x=0.4,xend=0.4, y=0, yend=Inf), colour="black") 
    

    enter image description here

    Update: You can get more space placing legend on top with theme(legend.position = 'top') I used your new data:

    enter image description here

    Update 2: With the new data, this is the closer I get about what you want (Just be careful about the colors in scale_fill_manual()), try this code:

    library(tidyverse)
    library(patchwork)
    #Create a split
    Fruit <- unique(Data$Fruit)
    Key <- sort(rep(c(1,2),length(Fruit)/2))
    DKeys <- data.frame(Fruit,Key)
    
    #Join data for splits
    Data2 <- Data %>% left_join(DKeys)
    
    #Now split
    List <- split(Data2,Data2$Key)
    
    #Plot function
    myplot <- function(x)
    {
      ForPlot <-  ggplot(x, aes(Colour, Values), fill=Colour)
      
      design <- theme(strip.background = element_blank(),
                      panel.background = element_blank(),  
                      panel.grid.major = element_blank(),
                      strip.placement = "outside",
                      panel.border=element_blank(),
                      #     axis.line = element_line(colour = "black"),
                      axis.line.x = element_line(colour = "white"),
                      axis.ticks.x=element_blank(),
                      legend.title = element_blank(),
                      # axis.text=element_text(size=8),
                      axis.text.x=element_blank(),
                      axis.title=element_text(size=10),
                      strip.text = element_text(size = 10),
                      legend.position = 'top') 
      
      
      ForPlot <- ForPlot+
        geom_hline(yintercept = c(0, 2.5, 5, 7.5, 10), colour= "lightgrey" )+
        geom_col(aes(fill=Colour), 
                 position=position_dodge2(preserve="single"))+
        ylab("Values") + xlab("Day") +
        facet_grid(.~Fruit,  scales= "free", space = 'free')+
        scale_y_continuous()+
        # scale_fill_discrete()+
        geom_text(aes(label = Day), position=position_dodge2(width= 0.9), 
                  y=-0.2, size=2.4) +
        geom_errorbar(aes(ymin=pmax(0,unten), ymax=oben), 
                      position=position_dodge2())+
        design+
        geom_segment(aes(x=0.4,xend=Inf, y=0, yend=0), color="black")+
        geom_segment(aes(x=0.4,xend=0.4, y=0, yend=Inf), colour="black")+
        scale_fill_manual(values=c(Blue='Blue',Green='Green',Purple='Purple',Red='Red',Yellow='Yellow'))
      return(ForPlot)
    }
    
    #Apply to plots
    List2 <- lapply(List,myplot)
    #Format 
    List2[2:length(List2)] <- lapply(List2[2:length(List2)], function(x) {x<-x+theme(legend.position = 'none')})
    names(List2) <- paste0('G',1:length(List))
    list2env(List2,envir = .GlobalEnv)
    #Arrange plots
    G1/G2+ plot_annotation(title = 'Fruity Colours')
    

    enter image description here