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?

user20650
  • 24,654
  • 5
  • 56
  • 91
Dekike
  • 1,264
  • 6
  • 17
  • 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 please – user20650 May 26 '20 at 19:09
  • Have you seen this StackOverflow? https://stackoverflow.com/questions/3681647/ggplot-how-to-increase-spacing-between-faceted-plots – Pablo Rodriguez May 26 '20 at 19:14
  • 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`. – Dekike May 26 '20 at 19:27
  • 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. – Dekike May 26 '20 at 19:30

1 Answers1

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

teunbrand
  • 33,645
  • 4
  • 37
  • 63