rggplot2facet-gridgeom-textannotate

How to add multiple labels to faceted ggplot outside of the plot?


I use facet_rep_grid to visualize different variables over the same x-axis. Now I would like to label the top left of each facet with "A", "B", "C" etc.

what i have looks similar to this, but with more difference in the y-axis between the single facets:

library(dplyr)
library(ggplot2)
library(ggthemes)
library(lemon)
library(grid)
library(cowplot) 

# mpg dataset from ggplot2

mylabs <- c("facet 1", " facet 2", 'facet 3', 'facet 4')
names(mylabs) <- c(4,5,6,8)

ggplot(mpg,aes(x=year, y=hwy)) + 
  geom_point()+
  facet_rep_grid(cyl~., switch='y', scales="free", labeller=labeller(cyl=mylabs))+
  theme(strip.placement = "outside",
        strip.background = element_blank(),
        axis.title.y = element_blank())


what I want is:

image

I tried adjusting this , which would be good for the "A" only.

ggplot(mpg,aes(x=year, y=hwy)) + 
  geom_point()+
  facet_rep_grid(cyl~., switch='y', scales="free", labeller=labeller(cyl=mylabs))+
  theme(strip.placement = "outside",
        strip.background = element_blank(),
        axis.title.y = element_blank())+
  
        labs(tag = "A/ only one") +
        coord_cartesian(clip = "off")

I also found this but i am unable to move the label outside of the plot.

ggplot(mpg,aes(x=year, y=hwy)) + 
  geom_point()+
  facet_rep_grid(cyl~., switch='y', scales="free", labeller=labeller(cyl=mylabs))+
  theme(strip.placement = "outside",
        strip.background = element_blank(),
        axis.title.y = element_blank())+

  coord_cartesian(clip = "off")+
  geom_text(data = myLab, aes(x = -500, y = 10, label = mylabs), hjust =0) 

Solution

  • One option would be to use patchwork, i.e. create your plot via separate charts. Afterwards you can add your tags easily via plot_annotation.

    library(ggplot2)
    #> Warning: package 'ggplot2' was built under R version 4.2.3
    library(patchwork)
    #> Warning: package 'patchwork' was built under R version 4.3.1
    
    mylabs <- c("facet 1", " facet 2", "facet 3", "facet 4")
    names(mylabs) <- c(4, 5, 6, 8)
    
    myfun <- function(.data, cyl) {
      remove_x <- if (cyl != "8") {
        theme(
          axis.title.x = element_blank(),
          axis.text.x = element_blank()
        )
      }
      ggplot(.data, aes(x = year, y = hwy)) +
        geom_point() +
        scale_x_continuous(limits = range(mpg$year)) +
        facet_grid(cyl ~ .,
          switch = "y", scales = "free_y",
          labeller = labeller(cyl = mylabs)
        ) +
        theme(
          strip.placement = "outside",
          strip.background = element_blank(),
          axis.title.y = element_blank(),
          plot.margin = margin()
        ) +
        remove_x
    }
    
    mpg |>
      split(~cyl) |>
      purrr::imap(
        myfun
      ) |>
      wrap_plots(ncol = 1) &
      plot_annotation(tag_levels = "A")