rggplot2plotfacetggh4x

Panels width/height depending on their text widgth/height with ggh4x::facet_nested()


I often do plots with ggplot and nested facets using facet_nested() from the ggh4x package. However, in some cases, I have somewhat long panel texts. In this case, all panels take the the longest width/height. Is there any way to have an adaptative width/height? Or even to manually specify the width/height of each "level" of the nested faceting?

Here is a simple dummy example, in which I illustrate my question with the width of the y-faceting:

library(ggplot2)
library(ggh4x)
library(dplyr)

data.frame(
  top1 = sample(c(1, 2, 3), size = 1000, replace = TRUE),
  left1 = sample(c("a", "b", "c"), size = 1000, replace = TRUE),
  left2 = sample(
    c("A medium text", "An even longer text\nwith several rows\nfoo"),
    size = 1000, replace = TRUE
  ),
  left3 = sample(c("d", "e", "f"), size = 1000, replace = TRUE),
  value = rnorm(1000)
) |>
  group_by(top1, left1, left2, left3) |>
  summarise(value = mean(value), .groups = "drop") |>
  ggplot() +
  ggh4x::facet_nested(
    left1 + left2 + left3 ~ top1,
    switch = "y", scales = "free",
    drop = TRUE, space = "free_y"
  ) +
  geom_tile(aes(x = 0, y = 0, fill = value)) +
  theme(
    axis.title = element_blank(),
    axis.ticks = element_blank(),
    axis.text = element_blank(),
    strip.text.y.left = element_text(angle = 0),
    strip.background.y = element_rect(fill = "grey90", colour = "grey10")
  )

Which gives:

Code result ggplot

What I'd like to know how to obtain, with this example specifically (manually edited):

enter image description here


Solution

  • By default the size for nested strips is set to constant. You can achieve the varying widths you're aiming for by setting strip_nested(size = "variable").

    data.frame(
      top1 = sample(c(1, 2, 3), size = 1000, replace = TRUE),
      left1 = sample(c("a", "b", "c"), size = 1000, replace = TRUE),
      left2 = sample(
        c("A medium text", "An even longer text\nwith several rows\nfoo"),
        size = 1000, replace = TRUE
      ),
      left3 = sample(c("d", "e", "f"), size = 1000, replace = TRUE),
      value = rnorm(1000)
    ) |>
      group_by(top1, left1, left2, left3) |>
      summarise(value = mean(value), .groups = "drop") |>
      ggplot() +
      ggh4x::facet_nested(
        left1 + left2 + left3 ~ top1,
        switch = "y", scales = "free",
        drop = TRUE, space = "free_y",
        strip = strip_nested(size = "variable")
      ) +
      geom_tile(aes(x = 0, y = 0, fill = value)) +
      theme(
        axis.title = element_blank(),
        axis.ticks = element_blank(),
        axis.text = element_blank(),
        strip.text.y.left = element_text(angle = 0),
        strip.background.y = element_rect(fill = "grey90", colour = "grey10")
      )