Search code examples
rggplot2axisaxis-labelsfacet-grid

ggplot2: Add border and colored background for axis title in faceted plot


I have a following R code

pdf <- data.frame(xx = as.factor(c(rep(0, 100), rep(1, 100))),
                  value = rnorm(200),
                  selected_site = c('y', rep('n', 98), 'y'),
                  name = as.factor(rep(1:5, each = 20)),
                  version = rep(c('A', 'B'), each = 100))

pdf %>%
  ggplot(aes(x = value, fill = xx)) +
  geom_histogram(alpha=0.6, position="identity") +
  facet_grid(selected_site ~ name, scale = 'free_y') + 
  scale_fill_manual(name = '', values = c('red', 'blue')) +
  facetted_pos_scales(
    y = list(selected_site == 'n' ~ scale_y_continuous(limits = c(0,5)),
             selected_site == 'y' ~ scale_y_continuous(limits = c(0,2)))) +
  xlab('') + ylab('THIS IS A TEST') +
  theme_bw() + 
  theme(legend.position = 'none',
        strip.background.y = element_blank(),
        strip.text.y = element_blank(),
        panel.spacing=unit(0.2, "lines"))

That produces this: enter image description here

I would like to create a background for the y-axis title where the background box height matches the height of the plot with a gray shade.

enter image description here

Is this possible to do? Maybe with textGrob?


Solution

  • I would probably do this by adding a slender text-only ggplot to the left of your main plot using patchwork

    library(ggh4x)
    library(patchwork)
    
    p2 <- pdf %>%
      ggplot(aes(x = value, fill = xx)) +
      geom_histogram(alpha=0.6, position="identity") +
      facet_grid(selected_site ~ name, scale = 'free_y') + 
      scale_fill_manual(name = '', values = c('red', 'blue')) +
      facetted_pos_scales(
        y = list(selected_site == 'n' ~ scale_y_continuous(limits = c(0,5)),
                 selected_site == 'y' ~ scale_y_continuous(limits = c(0,2)))) +
      xlab('') + ylab(NULL) +
      theme_bw() + 
      theme(legend.position = 'none',
            strip.background.y = element_blank(),
            strip.text.y = element_blank(),
            panel.spacing=unit(0.2, "lines"))
    
    p1 <- ggplot(data.frame(x = 1, y = 1, label = "THIS IS A TEST"), aes(x, y)) +
      geom_text(aes(label = label), angle = 90) +
      coord_cartesian(clip = "off") +
      theme_void() +
      theme(panel.background = element_rect(fill = "gray"),
            plot.margin = margin(5, 5, 5, 5))
    
    p1 + p2 + plot_layout(widths = c(1, 30))
    

    enter image description here