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")
With patchwork >= 1.2.0
it is now possible to collect the axis titles using the new axis_title=
parameter of plot_layout()
, i.e. similar to guides="collect"
one can now set axis_title="collect"
to add a shared axis titles.
library(ggplot2)
library(patchwork)
packageVersion("patchwork")
#> [1] '1.2.0'
gg1 <- ggplot(mtcars) +
aes(x = cyl, y = disp) +
geom_point() +
xlab("Disp") +
ylab("Hp // Cyl")
gg2 <- gg1 %+% aes(x = hp) +
xlab("Disp") +
ylab("Hp // Cyl")
gg1 + gg2 +
plot_layout(axis_titles = "collect")
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)