Search code examples
rggplot2patchwork

Controlling widths of many patchworked ggplots


I'm trying to make a graph with several ggplot2 graphs combined via patchwork.

I want first a shared y-axis for plot 1 and 3. Then plot 1 and 3 and at the end plot 2 and 4. This I have achieved with the help from @Allan Cameron - see the plot. Unfortunately I cannot control the width of plot 1,3,2 and 4. I would like plot 1 and 3 to be wider than plot 2 and 4. Also, for some reason the legend ends up in the middle of the plots. How can I put it all the way to the right?

Any ideas? All help is much appreaciated!

enter image description here

Here's the code:


mtcars

library(ggplot2)
library(patchwork)

p1 <- ggplot(mtcars) + 
  geom_point(aes(disp, wt, colour = mpg)) + 
  ggtitle('Plot 1')

p2 <- ggplot(mtcars) + 
  geom_point(aes(carb, wt)) + 
  ggtitle('Plot 2')


p3 <- ggplot(mtcars) + 
  geom_point(aes(hp, wt, colour = mpg)) + 
  ggtitle('Plot 3')

p4 <- ggplot(mtcars) + 
  geom_area(aes(gear, carb)) + 
  ggtitle('Plot 4')


# Patchwork graph with shared y-axis
y_axis <- ggplot(data.frame(l = p1$labels$y, x = 1, y = 1)) +
  geom_text(aes(x, y, label = l), angle = 90) + 
  theme_void() +
  coord_cartesian(clip = "off")

p1$labels$y <- p2$labels$y <- " "

y_axis + (p1 + p2) / (p3 + p4) + plot_layout(widths = c(1, 15, 5), guides = "collect")



Solution

  • With regards to the widths issue, the nesting you do -for example (p1 + p1)- causes the nested objects to respond differently. Instead you can use the design argument in plot_layout() to achieve the same, but responsive to the widths.

    library(ggplot2)
    library(patchwork)
    
    p1 <- ggplot(mtcars) + 
      geom_point(aes(disp, wt, colour = mpg)) + 
      ggtitle('Plot 1')
    
    p2 <- ggplot(mtcars) + 
      geom_point(aes(carb, wt)) + 
      ggtitle('Plot 2')
    
    
    p3 <- ggplot(mtcars) + 
      geom_point(aes(hp, wt, colour = mpg)) + 
      ggtitle('Plot 3')
    
    p4 <- ggplot(mtcars) + 
      geom_area(aes(gear, carb)) + 
      ggtitle('Plot 4')
    
    
    # Patchwork graph with shared y-axis
    y_axis <- ggplot(data.frame(l = p1$labels$y, x = 1, y = 1)) +
      geom_text(aes(x, y, label = l), angle = 90) + 
      theme_void() +
      coord_cartesian(clip = "off")
    
    p1$labels$y <- p2$labels$y <- " "
    
    y_axis + p1 + p2 + p3 + p4 +
      plot_layout(widths = c(1, 15, 5),
                  guides = "collect",
                  design = "
                  123
                  145
                  ")
    

    Created on 2020-12-16 by the reprex package (v0.3.0)

    Small note, you're deleting the y-axis lable of p2, whereas I think you meant to delete it from p3.