Search code examples
rggplot2facet-wrapfixed-width

Can I keep bar width constant in R facet plot with different number of categories in each facet?


I hope somebody can help me with my problem:

  • My data consists of categories that contain a number of up-regulated and down-regulated genes. I want them to show as horizontal, stacked columns. That works
  • I sorted generated these gene categories with two methods (Terms), UP_Keyword and GO-Term. They yielded different numbers of gene categories. No problem with facet wrap.
# A tibble: 10 x 4
   Category             Term       Reg   Reg_val  
   <chr>                 <chr>      <chr>   <dbl> 
 1 Transport            UP_Keyword Up         63  
 2 Transmembrane helix  UP_Keyword Up        341  
 3 Transmembrane        UP_Keyword Up        344  
 4 Transport            UP_Keyword Down        3  
 5 Transmembrane helix  UP_Keyword Down       12  
 6 Transmembrane        UP_Keyword Down        9  
 7 translation          GO_term    Up         41  
 8 glycolytic process   GO_term    Up          9  
 9 translation          GO_term    Down        0  
10 glycolytic process   GO_term    Down        1  
structure(
  list(
    Category = c(
      "Transport",
      "Transmembrane helix",
      "Transmembrane",
      "Transport",
      "Transmembrane helix",
      "Transmembrane",
      "translation",
      "glycolytic process",
      "translation",
      "glycolytic process"
    ),
    Term = c(
      "UP_Keyword",
      "UP_Keyword",
      "UP_Keyword",
      "UP_Keyword",
      "UP_Keyword",
      "UP_Keyword",
      "GO_term",
      "GO_term",
      "GO_term",
      "GO_term"
    ),
    Reg = c(
      "Up",
      "Up",
      "Up",
      "Down",
      "Down",
      "Down",
      "Up",
      "Up",
      "Down",
      "Down"
    ),
    Reg_val = c(63, 341, 344, 3, 12,
                9, 41, 9, 0, 1)
  ),
  row.names = c(NA,-10L),
  class = c("tbl_df",
            "tbl", "data.frame")
)
ex_plot <- ggplot(example_data, aes(x=Reg_val, y=Category, fill=Reg))+
  geom_col(width=0.5)+
  facet_wrap(.~Term, nrow=2, scales="free")

This is how my plot looks now

If someone has a solution for my problem, I would be very grateful. Please try to explain in a way a simple biologist can understand.


Solution

  • The facet_wrap() way of specifying facets doesn't allow for the space = "free" argument; this is an argument to facet_grid().

    Depending where you want the strip labels/facet titles to be, you can either use facet_grid() or use facet_row() from the ggforce package. Examples below.

    library(ggplot2)
    
    df <- data.frame(
      Category = c("Transport", "Transmembrane helix", "Transmembrane",
                   "Transport", "Transmembrane helix", "Transmembrane",
                   "translation", "glycolytic process",
                   "translation", "glycolytic process"),
      Term = rep(c("UP_Keyword", "GO_term"), c(6, 4)),
      Reg = rep(c("Up", "Down", "Up", "Down"), c(3, 3, 2, 2)),
      Reg_val = c(63, 341, 344, 3, 12, 9, 41, 9, 0, 1)
    )
    
    # Make the core plot
    plot <- ggplot(df, aes(Reg_val, Category, fill = Reg)) +
      geom_col(width = 0.5)
    
    plot + facet_grid(Term ~ ., scales = "free", space = "free")
    

    plot + ggforce::facet_col(~ Term, space = "free", scales = "free_y")
    

    Created on 2021-01-03 by the reprex package (v0.3.0)