Search code examples
rggplot2facet

Is it possible to cut the y-axis for a one row of facets only?


I have a Data frame like this:

   Value Time Colour Fruit
1    9.0    1    Red Apple
2    9.5    2    Red Apple
3   10.0    3    Red Apple
4    9.0    1   Blue Apple
5    9.5    2   Blue Apple
6   10.0    3   Blue Apple
7    1.0    1    Red  Pear
8    2.0    2    Red  Pear
9    3.0    3    Red  Pear
10   2.0    1   Blue  Pear
11   1.0    2   Blue  Pear
12   3.0    3   Blue  Pear

and the following Plot:

Plotprep <- ggplot(Data, aes(x=`Time`, y=Value, fill= Time))

Plotprep +
  geom_bar(position= position_dodge2(aes(fill=Time)), stat="identity", show.legend=FALSE)+
  ylab("Value") + xlab("Colour") +
  facet_grid(`Fruit`~`Colour`, scales = "free", space = "free_x", switch="y") +
  scale_y_continuous() + 
  theme(strip.background = element_blank(), 
        axis.text.x=element_text(),
        axis.line = element_line(colour = "black", linetype = "solid"))

Differences between the bars in the top row of facets are hard to see as they are relatively small compared to the bar size. Is there a way, that I can adjust the y scale only in this row to show the portion between 8 and 11? (Kind of like i could zoom-in in some graphic programs)

The two problem I faced were:

  1. everything I tried was used for all facets and;
  2. if I use limits of the y-Scales all Data extending these limits are lost.

Solution

  • Yes this is possible by setting the limits of the y-axis as a function. The following checks if the largest limit is bigger than 8 and cuts the y-axis at 8 if it is. You'd also need to control the oob argument specifically for bar plots, because they are internally parameterised as rectangles (so their ymin wil be out-of-bounds).

    library(ggplot2)
    
    zz <- "
       Value Time Colour Fruit
    1    9.0    1    Red Apple
    2    9.5    2    Red Apple
    3   10.0    3    Red Apple
    4    9.0    1   Blue Apple
    5    9.5    2   Blue Apple
    6   10.0    3   Blue Apple
    7    1.0    1    Red  Pear
    8    2.0    2    Red  Pear
    9    3.0    3    Red  Pear
    10   2.0    1   Blue  Pear
    11   1.0    2   Blue  Pear
    12   3.0    3   Blue  Pear"
    
    Data <- read.table(text = zz)
    
    Plotprep <- ggplot(Data, aes(x=`Time`, y=Value, fill= Time))
    
    
    Plotprep +
      geom_bar(position= position_dodge2(aes(fill=Time)), stat="identity", show.legend=FALSE)+
      ylab("Value") + xlab("Colour") +
      facet_grid(`Fruit`~`Colour`, scales = "free", space = "free_x", switch="y") +
      scale_y_continuous(
        limits = function(x) {
          if (x[2] > 8) {
            return(c(8, x[2]))
          } else {
            return(x)
          }
        }, oob = scales::oob_keep
      ) + 
      theme(strip.background = element_blank(), 
            axis.text.x=element_text(),
            axis.line = element_line(colour = "black", 
                                     linetype = "solid"))
    

    I also need to add that this isn't a good way to do it if for example the bottom row had range 0-15 and the top range has 7-9, since the 'is-larger-than-eight'-check doesn't separate your cases well enough.