0

Am following a very similar query to this previous question and answer from @Tung, where I'd like to annotate a facet_grid using letters on the outside of the plot. The wonderful egg::tag_facet_outside function is kind of what I'm after...

library(ggplot2)

p <- ggplot(mtcars, aes(qsec, mpg)) + 
  geom_point() + 
  facet_grid(cyl ~ am, switch = 'y') +
  theme_bw(base_size = 12) +
  theme(strip.placement = 'outside')

library(egg)
tag_facet_outside(p)

Which yields this...

enter image description here

My question is whether I can shift the roman numeral labels that are currently on the right hand side of the graph to the left hand side? Within tag_facet_outside() there is the option to specify parameters for tag_fun_right= as well as options of specifying coordinates but I just can't seem to get these labels to appear all the way over to the left.

Next one is - is it possible to remove the top row of tags altogether, possibly by specifying the tag_fun_top ? Any help appreciated! Thanks

Timmo83
  • 119
  • 5

1 Answers1

1

One option would be to stick with ggplot2 and use a custom labeller function and theme options. Basically, as far as I get it egg::tag_facet_outside is doing more or less the same under the hood.

library(ggplot2)

ggplot(mtcars, aes(qsec, mpg)) +
  geom_point() +
  facet_grid(cyl ~ am,
    switch = "y",
    labeller = labeller(
      am = ~ paste0("(", letters[as.numeric(factor(.x))], ")"),
      cyl = ~ paste0(as.roman(as.numeric(factor(.x))), ".")
    )
  ) +
  theme_bw(base_size = 12) +
  theme(
    strip.placement = "outside",
    strip.background = element_blank(),
    strip.text.x = element_text(hjust = 0, size = rel(1), face = "bold"),
    strip.text.y.left = element_text(vjust = 1, angle = 0, size = rel(1), face = "bold", margin = margin(t = 0, r = 5.5))
  )

To get rid off the top row of labels you could use theme(strip.text.x = element_blank()):

last_plot() +
  theme(strip.text.x = element_blank())

UPDATE Adding the annotations while still keeping the strip labels could be achieved via ggh4x::facet_grid2 like so. Basically I use a helper column cyl2 to add two layers of cyl facets where one is used for the annotations, while the second is used for the default strip labels. Via the strip argument ggh4x::facet_grid2 allows to style the two layers separately:

library(ggplot2)
library(ggh4x)

mtcars$cyl2 <- mtcars$cyl

ggplot(mtcars, aes(qsec, mpg)) +
  geom_point() +
  facet_nested(cyl + cyl2 ~ am,
             switch = "y",
             labeller = labeller(
               am = ~ paste0("(", letters[as.numeric(factor(.x))], ")"),
               cyl = ~ paste0(as.roman(as.numeric(factor(.x))), ".")
             ),
             strip = strip_themed(background_y = list(
               element_blank(),
               element_rect(fill = "grey85")
             ),
             text_y = list(
               element_text(vjust = 1, angle = 0, size = rel(1), face = "bold", margin = margin(t = 0, r = 5.5)),
               element_text(vjust = .5, angle = 90, size = rel(1), margin = margin(4.4, 4.4, 4.4, 4.4))
             ),
             by_layer_y = TRUE
             )
  ) +
  theme_bw(base_size = 12) +
  theme(
    strip.placement = "outside",
    strip.background = element_blank(),
    strip.text.x = element_text(hjust = 0, size = rel(1), face = "bold")
  )

stefan
  • 90,330
  • 6
  • 25
  • 51
  • Thank you greatly, really appreciate it. How would you go about adding those annotations whilst also retaining the horizontal strip chart labels, say to also indicate cyl for each row in the above example? – Timmo83 Sep 09 '22 at 05:31
  • Hi Timmo83. I just added an update to show one approach to add the annotations while retaining the default strip labels. – stefan Sep 09 '22 at 11:44
  • Ah of course! The ggh4x package is awesome but I didn't realize that function - even better. Thanks again! – Timmo83 Sep 11 '22 at 04:11