Search code examples
rggplot2geom-barfacet-grid

How can I change the color of my facet label (strip.background) to be the same as its bars?


I have a facet_grid plot that summarizes the distribution of genes per category as seen below. I want to change the color of the facet labels/strip.background (the one with red boxes and "Categories" in the code) to make it similar to its corresponding plot.

How do I also increase the spacing between bars (not between facets) to make it more readable? Since there are a lot of data as you can see on the y axis labels (covered by black boxes), it's being compressed and the labels become unreadable.

facet_grid plot

ggplot(allVFs, aes(x=Dist,y=genes)) + 
  geom_bar(stat="identity", width = 0.75, size = 0.05 ) +
  facet_grid(Categories ~., scales = "free", space = "free") +
  labs( x = "Distribution (%)", y = "Genes", title = "VFs per category" ) +
  theme( strip.text = element_text( size = 8, color = "white", hjust = 0.5),
         strip.text.y = element_text(angle=0),
         strip.background = element_rect( fill = "#5675D6"), # I tried changing this but couldn't make it similar to the bar colors
         panel.background = element_rect( fill = "#efefef"),
         panel.grid.major.x = element_blank(),
         panel.grid.minor.x = element_blank(),
         panel.grid.minor.y = element_blank(),
         panel.grid.major.y = element_line( color = "#C0C0C0" ),
         panel.spacing.x = unit( 0.8, "cm" ),
         panel.spacing.y = unit( 0.5, "cm" ),
         legend.position = "none" ) +
  geom_text(aes( label = paste0( Dist, "%" ), y = genes),
            vjust = 0, size = 2, color = "black" ) +
  aes(fill = as.factor(Categories)) #This gives the color to each facet that I want to replicate with the facet labels

Any suggestions to improve this plot would be greatly appreciated!


Solution

  • This is not possible out-of-the-box in ggplot2, but we can dig into the gtable object to achieve the result.

    I'll use an example plot and data. But this should work on you example too:

    library(ggplot2)
    g <- ggplot(iris, aes(x = Sepal.Length, fill = Species)) +
      geom_bar() +
      facet_grid(Species ~ .)
    
    # Find the colors used
    fill_colors <- unique(ggplot_build(g)$data[[1]]$fill)
    
    # Find strips glob
    gt<-ggplot_gtable(ggplot_build(g))
    strips <- which(startsWith(gt$layout$name,'strip'))
    
    # Change the fill color of each strip
    for (s in seq_along(strips)) {
      gt$grobs[[strips[s]]]$grobs[[1]]$children[[1]]$gp$fill <- fill_colors[s]
    }
    
    plot(gt)
    

    Created on 2020-11-26 by the reprex package (v0.3.0)

    What we are doing is finding the grid object that holds each strip, and changing its fill attribute manually using the colors extracted from the plot.