3

Based on the code and data below, is it possible to have common legend labels without having to remove xlab and ylab from the ggplot codes using patchwork?

The reason why I ask this is because I have lots of ggplots and so I don't find it ideal to remove xlab and ylab from each of the ggplots and then use the method in the code. I know I can use ggarrange but ggpubr is much slower than patchwork.

Sample data and code:

library(tidyverse)
library(patchwork)
library(gridextra)

gg1 = ggplot(mtcars) +
  aes(x = cyl, y = disp) +
  geom_point() +
  xlab("Disp") +
  ylab("Hp // Cyl") +
  theme(axis.title = element_blank())

gg2 = gg1 %+% aes(x = hp) +
  xlab("Disp") +
  ylab("Hp // Cyl")

# This method still keeps the individual axis labels.
p = gg1 + gg2
gt = patchwork::patchworkGrob(p)
gridExtra::grid.arrange(gt, left = "Disp", bottom = "Hp // Cyl")
Ed_Gravy
  • 1,841
  • 2
  • 11
  • 34

2 Answers2

4

One possible option to have a common axis title without having to remove xlab and ylab from the ggplot code would be to remove the axis labels via & labs(...) when creating the patch and adding a common axis title as a separate plot where I made use of cowplot::get_plot_component to create the axis title plot:

library(ggplot2)
library(patchwork)
library(cowplot)


gg1 <- ggplot(mtcars) +
  aes(x = cyl, y = disp) +
  geom_point() +
  xlab("Disp") +
  ylab("Hp // Cyl") +
  theme(axis.title = element_blank())

gg2 <- gg1 %+% aes(x = hp) +
  xlab("Disp") +
  ylab("Hp // Cyl")

gg_axis <- cowplot::get_plot_component(ggplot() +
  labs(x = "Hp // Cyl"), "xlab-b")

(gg1 + gg2 & labs(x = NULL, y = NULL)) / gg_axis + plot_layout(heights = c(40, 1))

UPDATE To add a y-axis it's basically the same. To get the left y axis title we have to use ylab-l. Additionally, we have to add a spacer to the patch. IMHO the best approach in this case would be to put all components in a list and use the design argument of plot_layout to place them in the patch.

p <- ggplot() + labs(x = "Hp // Cyl", y = "Disp")
x_axis <- cowplot::get_plot_component(p, "xlab-b")
y_axis <- cowplot::get_plot_component(p, "ylab-l")

design = "
DAB
#CC
"

list(
  gg1 + labs(x = NULL, y = NULL), # A
  gg2 + labs(x = NULL, y = NULL), # B
  x_axis,# C
  y_axis # D
) |> 
  wrap_plots() + 
  plot_layout(heights = c(40, 1), widths = c(1, 50, 50), design = design)
stefan
  • 90,330
  • 6
  • 25
  • 51
  • Cheers, so for the `y-axis` label should I add `labs(x = "Hp // Cyl"), "xlab-b", y = "Disp", "ylab-b"` ? – Ed_Gravy Jul 20 '22 at 00:55
  • 1
    A bit more work than that. :) See my update. – stefan Jul 20 '22 at 05:41
  • Good day Stefan, the code is not seem to be working as intended with my code, the code and data is the same as in this [question](https://stackoverflow.com/questions/73043424/r-ggplot2-patchwork-changes-label-location/73043626?noredirect=1#comment129009203_73043626). Should I edit my question and add the code and data here? – Ed_Gravy Jul 20 '22 at 11:35
3

You could also just make a blank plot with the label you need, then use plotlayout() with a high width ratio to combine.

blanklabelplot<-ggplot()+labs(y="your title")+theme_classic()+ 
  guides(x = "none", y = "none")
  
blanklabelplot+plot+ plot_layout(widths=c(1,1000))