In the most straightforward case, the patchwork
does a good job of pairing its two panels, but it also seems to ignore the subdiagram's specification of the location of the legend legend.box.spacing
:
library(ggplot2)
p <- ggplot(mtcars, aes(wt, mpg))
p + geom_point(aes(colour = factor(cyl)))
p1 <- p + geom_point(aes(colour = cyl))+
theme(legend.box.spacing = unit(20, 'pt'))
p2 <- p + geom_point(aes(colour = cyl*100))+
theme(legend.box.spacing = unit(20, 'pt'))
patchwork::wrap_plots(p1, p2, ncol = 1)
This should align the overall width of the two figures (use free
):
At this time the legend and panel should be positioned according to their respective settings.
patchwork::wrap_plots(free(p1), free(p2), ncol = 1)
The result with collect is very close to the expected result. But it doesn't align with the respective subgraphs, which is also not appropriate.
patchwork::wrap_plots(p1, p2, ncol = 1, guides = 'collect')
So is there a way to be able to align the panels and at the same time make sure that the legend of each subfigure is fixed to its own panel position as specified?
#Edit1:
Problems arise when there are multiple levels of wrap_plots
.
In my practical use, it is the merging process of multiple raster data that is not aligned, should I avoid using wrap_plots
multiple times?
The following code is my reproduction of the process:
library(ggplot)
library(terra)
library(tidyterra)
library(patchwork)
# raster data
r1 <- rast(nrow = 10, ncol = 10)
values(r1) <- 1:ncell(r1)
r2 <- r1 * r1
rr <- c(r1, r2) |>
`names<-`(c("r1", "r2"))
p1 <- ggplot() +
geom_spatraster(data = rr) +
facet_wrap(~lyr)
p2 <- ggplot() +
geom_spatraster(data = r1) +
facet_wrap(~lyr)
p3 <- ggplot() +
geom_spatraster(data = rr / 10) +
facet_wrap(~lyr)
p4 <- ggplot() +
geom_spatraster(data = r2) +
facet_wrap(~lyr)
design = 'aab
ccd'
patchwork::wrap_plots(p1, p2, p3, p4, ncol = 2, design = design) &
theme(
legend.box.background = element_rect(color = 'red'),
legend.justification = 'left'
)
Everything is fine, left aligned as expected.
BUT: Even &
not *
fails to work on all subgraphs.
sub1 <- wrap_plots(p1, p2, design = 'aab')
sub2 <- wrap_plots(p3, p4, design = 'aab')
wrap_plots(sub1, sub2, ncol = 1) &
theme(
legend.box.background = element_rect(color = 'blue'),
legend.justification = 'left'
)
One option to achieve your desired result would be to set the justification of both legends to "left"
:
Note: Just for the reprex I added a red outline around the legend boxes.
library(ggplot2)
library(patchwork)
p <- ggplot(mtcars, aes(wt, mpg))
p1 <- p + geom_point(aes(colour = cyl))
p2 <- p + geom_point(aes(colour = cyl * 100))
patchwork::wrap_plots(p1, p2, ncol = 1) &
theme(
legend.box.background = element_rect(color = "red"),
legend.box.spacing = unit(20, "pt"),
legend.justification.right = "left"
)