Home > Software engineering >  Aligning and scaling ggplots with patchwork
Aligning and scaling ggplots with patchwork

Time:12-28

I'm trying to make a combine some plots into a single plot using the patchwork package, but I'm unfamiliar with it and am having trouble figuring out to how to properly scale the size of the plots. There's one core plot, the scatter plot, and then a boxplot for each continuous variable to some the distributions as well. Here's a reproducible example below:

library(dplyr)
library(ggplot2)
library(patchwork)

set.seed(100)
dat1 <- tibble(x = runif(1000, 0, 10),
               y = runif(1000, 0, 20),
               group1 = sample(rep(letters[1:5], each = 200)),
               group2 = sample(rep(letters[-22:-1], each = 250)))

plot1 <- ggplot(data = dat1)  
  geom_point(aes(x = x, y = y, color = group1))  
  facet_wrap(~group2)  
  theme(legend.position = 'bottom')

xbox <- ggplot(data = dat1)  
  geom_boxplot(aes(x = x, y = group1, fill = group1, color = group1))  
  scale_x_continuous(position = 'top')  
  theme(legend.position = 'none',
        axis.title.y = element_blank(),
        axis.text.y = element_blank(),
        axis.ticks.y = element_blank(),
        title = element_blank())

ybox <- ggplot(data = dat1)  
  geom_boxplot(aes(x = group1, y = y, fill = group1, color = group1))  
  scale_y_continuous(position = 'right')  
  theme(legend.position = 'none',
        axis.title.x = element_blank(),
        axis.text.x = element_blank(),
        axis.ticks.x = element_blank(),
        title = element_blank())

(xbox   plot_spacer()) / (plot1   ybox)

enter image description here

This is close to what I'm attempting, but the boxplots need to be rescaled such that the top one is approximately 20% of its shown height and the righthand one is approximately 20% of its shown width. I've tried using patchwork::plot_layout to handle the scaling, but I keep getting unexpected results. I inserted the patchwork::plot_spacer() so that the righthand boxplot wouldn't stretch the whole height of picture but maybe there is a better way to do that. The boxplots are supposed to appear more like axes, so that upper right whitespace shouldn't really be there.

CodePudding user response:

I'm not certain you'll get a plot that makes inferential sense in the margins, but you can change the widths and heights of the marginal plots in plot_layout using either the heights and widths arguments or the design argument. Note that plots in parenthesis are considered "subplots" themselves and is given their own "area" when using plot_layout. As such I've added all plots together rather than arranging them using other patchwork operators.

xbox   plot_spacer()   plot1   ybox   plot_layout(design = c(area(t = 1, b = 1, l = 1, r = 6), # <== top column
                                                             area(t = 1, b = 1, l = 7, r = 7), # <== top right
                                                             area(t = 2, b = 7, l = 1, r = 6), # <== bottom left
                                                             area(t = 2, b = 7, l = 7, r = 7)  # <== bottom right
                                                             ))
# Alternative:
xbox   plot_spacer()   plot1   ybox   plot_layout(ncol = 2, nrow = 2, 
                                                  heights = c(1, 6),
                                                  widths = c(6, 1))

enter image description here

  • Related