How to increase space among different boxes created for the facet labels using `facet_nested`?
Asked Answered
H

1

2

I have a plot like this below:

library(ggplot2)
library(ggh4x) # remotes::install_github("teunbrand/ggh4x")

df1 <- data.frame(x = rep(1:12, times=4, each=1), 
                  y = rep((1:12)^2, times=4, each=1),
                  Variable1 = rep(c("A","B"), times=1, each=24),
                  Variable2 = rep(c("C","D"), times=4, each=12))


g<-ggplot(df1, aes(x=x, y=y)) + 
  geom_point(size=1.5) + 
  theme(strip.background = element_rect(colour = "black", fill = "white", 
                                        size = 1.5, linetype = "solid"),
        axis.title.x =element_text(margin = margin(t = 2, r = 20, b = 0, l = 0),size = 16),
        axis.title.y =element_text(margin = margin(t = 2, r = 20, b = 0, l = 0),size = 16),
        axis.text.x = element_text(angle = 0, hjust = 0.5,size = 14),
        axis.text.y = element_text(angle = 0, hjust = 0.5,size = 14),
        strip.text.x = element_text(size = 14),
        strip.text.y = element_text(size = 13),
        axis.line = element_line(),
        panel.grid.major= element_blank(),
        panel.grid.minor = element_blank(),
        legend.text=element_text(size=15),
        legend.title = element_text(size=15,face="bold"),
        legend.key=element_blank(),
        legend.position = "right",
        panel.border = element_blank(),
        strip.placement = "outside",
        strip.switch.pad.grid = unit('0.25', "cm")) + 
  facet_nested( .~Variable1 + Variable2)

g

enter image description here

How could I increase the space among different boxes for the different facet labels? So for example, I want to increase the space between A and C/D. In this post is explained how to change the distance between the plot edge and the facet labels (using strip.switch.pad.grid in theme), but it doesn't work for separating facet boxes among them.

Does anyone know how to do it?

Hawser answered 26/5, 2020 at 19:4 Comment(4)
Can I check ; are you wanting to add a little vertical space between, for example, box A and boxes C & D? ps what package is facet_nested from pleaseCapitol
Have you seen this StackOverflow? #3682147Ora
Thanks @user20650. I think facet_nested comes from the package ggh4x. And regarding the question, yes, I want to increase space between A and C or A and D.Hawser
Regarding the post @PabloRodriguez, yes, I saw it but I thought it is not related to my question since it doesn't mention facet_nested, which is the only function which allows the alignment of different facet boxes as far as I know.Hawser
G
2

ggplot2 and ggh4x don't have options to place the facet strips apart. However, that doesn't mean it can't be done: it just means that the solution is a bit uglier than you'd like. Because you'd have to dive into the gtable/grid structures underneath ggplot.

For completeness; this gives identical output to your code.

library(ggplot2)
library(ggh4x)
library(grid)

df1 <- data.frame(x = rep(1:12, times=4, each=1), 
                  y = rep((1:12)^2, times=4, each=1),
                  Variable1 = rep(c("A","B"), times=1, each=24),
                  Variable2 = rep(c("C","D"), times=4, each=12))



g<-ggplot(df1, aes(x=x, y=y)) + 
  geom_point(size=1.5) + 
  theme(strip.background = element_rect(colour = "black", fill = "white", 
                                        size = 1.5, linetype = "solid"),
        axis.title.x =element_text(margin = margin(t = 2, r = 20, b = 0, l = 0),size = 16),
        axis.title.y =element_text(margin = margin(t = 2, r = 20, b = 0, l = 0),size = 16),
        axis.text.x = element_text(angle = 0, hjust = 0.5,size = 14),
        axis.text.y = element_text(angle = 0, hjust = 0.5,size = 14),
        strip.text.x = element_text(size = 14),
        strip.text.y = element_text(size = 13),
        axis.line = element_line(),
        panel.grid.major= element_blank(),
        panel.grid.minor = element_blank(),
        legend.text=element_text(size=15),
        legend.title = element_text(size=15,face="bold"),
        legend.key=element_blank(),
        legend.position = "right",
        panel.border = element_blank(),
        strip.placement = "outside",
        strip.switch.pad.grid = unit('0.25', "cm")) + 
  facet_nested( .~Variable1 + Variable2)

Then here is the extra steps that you'd have to take for your plot, or any plot where the strip layout is horizontal without vertical strips. This should work for regular facet_grid() too.

# How much to push the boxes apart
space <- unit(0.5, "cm")

# Convert to gtable
gt <- ggplotGrob(g)

# Find strip in gtable
is_strip <- which(grepl("strip", gt$layout$name))
strip_row <- unique(gt$layout$t[is_strip])

# Change cell height
gt$heights[strip_row] <- gt$heights[strip_row] + space

# Add space to strips themselves
gt$grobs[is_strip] <- lapply(gt$grobs[is_strip], function(strip) {
  gtable::gtable_add_row_space(strip, space)
})

# Render
grid.newpage(); grid.draw(gt)

Created on 2020-05-26 by the reprex package (v0.3.0)

Note that this example is on R4.0.0. The grid::unit() arithmetic behaviour might be slightly different in previous R versions.

As an aside, if you just want to add padding to the text, it is easier to just wrap newlines around the text:

df1$Variable1 <- factor(df1$Variable1)
levels(df1$Variable1) <- paste0("\n", levels(df1$Variable1), "\n")

EDIT: It might just be easiest to use ggtext textbox elements:

library(ggtext) # remotes::install_github("wilkelab/ggtext")
g + theme(
  strip.background = element_blank(),
    strip.text = element_textbox_simple(
      padding = margin(5, 0, 5, 0),
      margin = margin(5, 0, 5, 0),
      size = 13,
      halign = 0.5,
      fill = "white",
      box.color = "black",
      linewidth = 1.5,
      linetype = "solid",
    )
)
g

Gwendagwendolen answered 26/5, 2020 at 19:47 Comment(1)
Thanks for your time @teunbrand. It looks it works!Hawser

© 2022 - 2025 — McMap. All rights reserved.