Home > Back-end >  Add space argument to facet_wrap
Add space argument to facet_wrap

Time:12-16

facet_wrap() has been recognized for not having a space = "free" argument (enter image description here

Create the above figure using the following code:

library(tidyverse)

p <-
  mtcars %>%
  rownames_to_column() %>%
  ggplot(aes(x = disp, y = rowname))   geom_point()  
  facet_wrap(~ carb, ncol = 1, scales = "free_y")

facet_grid on the other hand has a space = "free" argument. Allowing for nice y-axis spacing.

enter image description here

Create the above figure using the following code:

p <-
  mtcars %>%
  rownames_to_column() %>%
  ggplot(aes(x = disp, y = rowname))   geom_point()   
  facet_grid(carb ~ ., scales = "free_y", space = "free_y")

The issue with this is that the label is on the side, not the top. I sometimes have longer facet labels and few rows in the facet. This means the facet label gets cut off.

There is a solution from the package (comment by ilarischeinin on https://github.com/tidyverse/ggplot2/issues/2933).

p <-
  mtcars %>%
  rownames_to_column() %>%
  ggplot(aes(x = disp, y = rowname))   geom_point()

p   ggforce::facet_col(vars(carb), scales = "free_y", space = "free")

But, there are limitations leaving . For example, I ultimately want a two column figure, and this functionality does not seem possible with . Is there any way to produce the same result using facet_wrap() so that I can utilize the ncol() argument?

CodePudding user response:

Here is a potential workaround based on https://stackoverflow.com/a/29022188/12957340 :

library(tidyverse)
library(gtable)
library(grid)

p1 <- mtcars %>%
  rownames_to_column() %>%
  ggplot(aes(x = disp, y = rowname))   geom_point()  
  facet_grid(carb ~ ., scales = "free_y", space = "free_y")  
  theme(panel.spacing = unit(1, 'lines'),
        strip.text.y = element_text(angle = 0))

gt <- ggplotGrob(p1)
panels <-c(subset(gt$layout, grepl("panel", gt$layout$name), se=t:r))
for(i in rev(panels$t-1)) {
  gt = gtable_add_rows(gt, unit(0.5, "lines"), i)
}
panels <-c(subset(gt$layout, grepl("panel", gt$layout$name), se=t:r))
strips <- c(subset(gt$layout, grepl("strip-r", gt$layout$name), se=t:r))
stripText = gtable_filter(gt, "strip-r")
for(i in 1:length(strips$t)) {
  gt = gtable_add_grob(gt, stripText$grobs[[i]]$grobs[[1]], t=panels$t[i]-1, l=5)
}
gt = gt[,-6]
for(i in panels$t) {
  gt$heights[i-1] = unit(0.8, "lines")
  gt$heights[i-2] = unit(0.2, "lines")
}
grid.newpage()
grid.draw(gt)

Created on 2021-12-15 by the reprex package (v2.0.1)

It's not clear to me what you mean by "I ultimately want a two column figure", but if you can come up with an example to illustrate your 'ultimate' expected outcome I can try to adapt this approach and see if it will work or not.

  • Related