7

Is there a canonical way to add facet titles within facet_grid? Or a way to specific row labels in facet_wrap? (Without geom_text, geom_label, or grob manipulation.)

Consider:

dat <- data.frame(rowInd = paste0("R", c(1, 2, 2, 3, 3, 3)), colInd = paste0("C", c(1, 1, 2, 1, 2, 3)),
                  facetName = c("1-10", "60-70", "80-90", "100-110", "120-130", "140-150"), val=1:6)
dat
#   rowInd colInd facetName val
# 1     R1     C1      1-10   1
# 2     R2     C1     60-70   2
# 3     R2     C2     80-90   3
# 4     R3     C1   100-110   4
# 5     R3     C2   120-130   5
# 6     R3     C3   140-150   6

Direct plots give:

library(ggplot2)
ggplot(dat, aes(x=1, y=val)) + facet_grid(rowInd ~ facetName, switch="y") # 1
ggplot(dat, aes(x=1, y=val)) + facet_wrap(rowInd ~ facetName)             # 2
ggplot(dat, aes(x=1, y=val)) + facet_grid(rowInd ~ colInd, switch="y")    # 3

three ggplot2 plots with various faceting

Where:

  1. includes the row and facet labels I want, but not all facet labels apply to all rows;
  2. correctly associates a row-label ("R1") with a facet label, and one label per facet, but loses the row affiliation between facets;
  3. loses facet labels.

Ultimately I'm trying to do something akin to one of the below: two ggplot2 fake plots

I can "fill out" the data if needed (perhaps to facilitate the right plot), though it would be great to have them automatically hollow-plots or empty space.

r2evans
  • 141,215
  • 6
  • 77
  • 149
  • Probably the easiest way to create the plot on the right would be to merge 3 plots, 1 for each row. – Axeman Jun 23 '20 at 17:54
  • Yeah, sorry, that's something I'm trying to avoid as well, but that's also an option. Thanks, @Axeman. – r2evans Jun 23 '20 at 18:10

1 Answers1

1

Because you have not explicitly excluded the "patchwork" option... Following Axeman's lead, here an attempt to automate it.

I know it's a bit hacky, and the y-labels recur (that certainly need some tweaking), and it's certainly not "canonical", but it was kind of fun to put together ... :)

library(tidyverse)
library(patchwork)
dat <- data.frame(rowInd = paste0("R", c(1, 2, 2, 3, 3, 3)), colInd = paste0("C", c(1, 1, 2, 1, 2, 3)),
                  facetName = c("1-10", "60-70", "80-90", "100-110", "120-130", "140-150"), val=1:6)

ls_p <- 
  dat %>% 
  mutate(row_facet= paste(rowInd, facetName, sep = "_")) %>%
  split(., .$row_facet) %>%
  purrr::map(., .f = ~ {
    ggplot(., aes(x=1, y=val)) + facet_grid(rowInd ~ facetName, switch = "y")})

split_ls <- split(ls_p, dat$rowInd)

lengths_rowInd <- lengths(split_ls) 
col_len <- max(lengths_rowInd)
lengths_empty <- col_len - lengths_rowInd

p_empty <- ggplot() + theme_void()
ls_empty_p <- lapply(lengths_empty, function(x) rep(list(p_empty), x))

ls_filled_p <- Map(append, split_ls, ls_empty_p)
new_list <- do.call(list, unlist(ls_filled_p, recursive=FALSE))

wrap_plots(new_list)

Created on 2020-06-23 by the reprex package (v0.3.0)

tjebo
  • 21,977
  • 7
  • 58
  • 94
  • 1
    Since you mentioned `patchwork` (new to me), you might do three plots (instead of six here), and stack them with `p1 / p2 / p3` (spacers notwithstanding)... nice recommendation, thank you – r2evans Jun 23 '20 at 20:29
  • 1
    ... but now I see the method of your madness here ... the `theme_void()` is a nice touch. – r2evans Jun 23 '20 at 21:38
  • @r2evans thanks :) there might be more elegant methods of creating those lists with empty plots though – tjebo Jun 23 '20 at 21:48
  • 1
    I've been trying for something more elegant and theme-agnostic and such so that I can continue (as far as possible) with `ggplot2`-methods in and around it. – r2evans Jun 23 '20 at 21:50
  • 1
    Simply `ggplot()` creates an empty plot nowadays, should not need a theme (I think?). Also see `patchwork::plot_spacer` for a formal way of defining an empty plot, since you're already using `patchwork`. – Axeman Jun 25 '20 at 21:57
  • 1
    @Axeman thanks! I tried ggplot() but is drawing a grey area. I am not sure how I could use plot_spacer in the above method, but it is good to know about it, I wasn't aware :) – tjebo Jun 26 '20 at 09:42