How to Fix patchwork Not Collecting Size Guides in ggplot2
Understanding Why patchwork Fails to Collect Certain Guides
When combining multiple ggplot2 plots using the patchwork package, the guides = "collect" option is incredibly useful for creating clean, publication-ready figures. However, you might sometimes find that while some legends (like fill or color) merge seamlessly, others (like size) remain stubbornly duplicated.
This issue occurs because patchwork will only collect and merge guides if the scales are mathematically identical. If ggplot2 detects even a slight difference in scale limits, breaks, or labels between the plots, it treats them as distinct legends and refuses to merge them.
The Root Cause: Dynamic Scale Limits
In your original plotting function, you might have defined the size scale like this:
scale_size(range = c(2, 6), breaks = c(0.6, 0.75, 0.9), guide = guide_legend(title = "Size"))Because you did not explicitly define the limits parameter, ggplot2 automatically calculates the limits based on the range of the data in each individual dataset (df1 and df2). Since the random values for size_var differ between the two dataframes, the calculated limits are different. As a result, patchwork views the two size scales as incompatible and keeps their legends separate.
The Solution: Explicitly Define Scale Limits
To fix this, you must explicitly define the limits in your scale function so that both plots share the exact same scale definition. Here is how you can update your code:
library(ggplot2)
library(patchwork)
set.seed(1)
df1 <- data.frame(x = rnorm(30), y = rnorm(30),
fill_var = runif(30), size_var = runif(30, 0.5, 1))
df2 <- data.frame(x = rnorm(30), y = rnorm(30),
fill_var = runif(30), size_var = runif(30, 0.5, 1))
make_panel <- function(df) {
ggplot(df, aes(x, y)) +
geom_point(aes(fill = fill_var, size = size_var), shape = 21) +
scale_fill_viridis_b(breaks = c(0.25, 0.5, 0.75), limits = c(0, 1),
name = "Fill") +
# Define explicit limits here:
scale_size(range = c(2, 6), breaks = c(0.6, 0.75, 0.9),
limits = c(0.5, 1),
guide = guide_legend(title = "Size"))
}
wrap_plots(make_panel(df1), make_panel(df2), guides = "collect") &
theme(legend.position = "bottom")Summary Checklist for Collecting Legends in patchwork
If you ever run into a situation where guides = "collect" is not working as expected, verify the following properties across all plots:
- Limits: Are the
limitsexplicitly defined and identical? - Breaks: Do they share the same
breaks? - Labels: Are the legend
labelsand scale names exactly the same? - Guides: Are the guide properties (e.g.,
guide_legend()settings) identical?
By ensuring absolute consistency across these parameters, patchwork will reliably merge your legends every time.