guides = "collect"
does its job but it locates the legend in a way that it overlaps the plot. I would like it to be placed right in the middle of the empty bottom right corner, but it appears to be difficult since theme(legend.position = c(X,Y))
does not work with patchwork
Illustration of the issue:
This is the code I have for assembling 4 graphs I have using patchwork
. Pretty sure there is a more elegant way to use theme()
but I am quite new to patchwork
and it worked for me so far, except for the legend positioning.
A similar issue was resolved here but it does not seem to help in my case.
#first panel
s_wpanels_final <- (dots & theme_bw() & theme(axis.title.x =
element_blank(), panel.grid.minor.y = element_blank())) +
#second panel
(g_box_tmax & theme_bw() & theme(axis.text.x=element_blank(),
axis.ticks.x=element_blank(), panel.grid.minor.y = element_blank(),
axis.text.y=element_blank(), axis.ticks.y=element_blank(),
axis.title.x = element_blank(), legend.position = "none")) +
#third panel
(g_box_t0 & theme_bw() & theme(axis.text.x=element_blank(),
axis.ticks.x=element_blank(), panel.grid.minor.y = element_blank(),
axis.text.y=element_blank(), axis.ticks.y=element_blank(),
axis.title.x = element_blank(), legend.position = "none")) +
#fourth panel
(tmax_box & theme_bw() & theme(axis.text.x=element_blank(),
axis.ticks.x=element_blank(), axis.text.y=element_blank(),
axis.ticks.y=element_blank(), axis.title.y = element_blank(),
legend.position = "none")) +
guide_area()+
plot_layout(ncol=3, guides = "collect", widths=c(6,1,1), heights=c(6,1)) &
theme(legend.direction = "vertical", legend.box = "horizontal")
There are two issues with your code. First using +
to glue your plots together and setting ncol=3
will place the guide_area
in the second column of the second row. To center the legend I would suggest to use the design
argument to specify the layout of the plot. Second, while the plot panels will adjust to the space set via the height
and width arguments and the size of your plotting device, the legend will not, i.e. if the legend will not fit into the space given it will overlap with the surrounding panels. To fix that I would suggest to increase the widths of the second and third columns and the height of the second row. But as I said this also depends on the size of the plotting device.
Using some fake example plot based on mtcars
(see below) let's first reproduce your issue:
library(ggplot2)
library(patchwork)
list(
dots,
g_box_tmax,
g_box_t0,
tmax_box,
guide_area()
) |>
wrap_plots() +
plot_layout(guides = "collect", widths = c(6, 1, 1), heights = c(6, 1), ncol = 3) &
theme(legend.direction = "vertical", legend.box = "horizontal")
However, specifying the layout via the design
argument and increasing the height of the second row as well as the widths of the second and third columns works fine and centers the legend in the guide area:
design <-
"
ABC
DEE
"
list(
dots,
g_box_tmax,
g_box_t0,
tmax_box,
guide_area()
) |>
wrap_plots() +
plot_layout(guides = "collect", widths = c(6, 1.5, 1.5), heights = c(6, 1.5), design = design) &
theme(legend.direction = "vertical", legend.box = "horizontal")
PLOTS
dots <- ggplot(mtcars, aes(mpg, hp, color = factor(cyl), size = qsec)) +
geom_point() +
theme_bw() +
theme(
axis.title.x = element_blank(),
panel.grid.minor.y = element_blank()
)
g_box_tmax <- g_box_t0 <- ggplot(mtcars, aes(factor(cyl), hp, fill = factor(cyl))) +
geom_boxplot() +
theme_bw() +
theme(
axis.text.x = element_blank(),
axis.ticks.x = element_blank(), panel.grid.minor.y = element_blank(),
axis.text.y = element_blank(), axis.ticks.y = element_blank(),
axis.title.x = element_blank(), legend.position = "none"
)
tmax_box <- ggplot(mtcars, aes(mpg, factor(cyl), fill = factor(cyl))) +
geom_boxplot() +
theme_bw() +
theme(
axis.text.x = element_blank(),
axis.ticks.x = element_blank(), axis.text.y = element_blank(),
axis.ticks.y = element_blank(), axis.title.y = element_blank(),
legend.position = "none"
)