Written and maintained by CASRAI Editorial Board
Published
On this page
patchwork is an R package that combines separate ggplot2 plots into one graphic using arithmetic-style operators. Its documentation describes the aim as making it "ridiculously simple to combine separate ggplots into the same graphic". This page is for researchers and analysts who need a multi-panel figure (for example a Figure 1 with panels A to D) and want the commands, the layout controls and the common stumbling blocks in one place. Version 1.3.2 was the current CRAN release when this page was checked on 2026-11-08.
What patchwork is used for in research
patchwork assembles several ggplot2 objects into a single figure while keeping the panels aligned. The package site says it offers "rich support for arbitrarily complex layouts with full alignment". Typical research uses are a multi-panel manuscript figure, a shared legend across panels, and automatic panel labels such as A, B, C. It works on ggplot2 plots only; if you are new to the plotting layer itself, see ggplot themes, ggplot titles and the introduction to using RStudio.
Install or access
The official CRAN listing (checked 2026-11-08) gives version 1.3.2, published 2025-08-25, under an MIT + file LICENSE. It imports ggplot2 (3.0.0 or later), gtable (0.3.6 or later), rlang (1.0.0 or later), cli and farver.
install.packages("patchwork")
library(patchwork)
The development version is installed from GitHub with devtools::install_github("thomasp85/patchwork"), as stated on the package site.
Step-by-step: build a multi-panel figure
- Create the individual plots and store each in a variable (the example uses R’s built-in
mtcarsdata). - Combine them with operators.
p1 + p2combines plots,|places plots side by side,/stacks them, and parentheses nest groups. - Control the layout with
plot_layout(). - Label and title the whole figure with
plot_annotation().
library(ggplot2)
library(patchwork)
p1 <- ggplot(mtcars, aes(mpg, wt, colour = factor(cyl))) + geom_point()
p2 <- ggplot(mtcars, aes(factor(cyl), mpg)) + geom_boxplot()
p3 <- ggplot(mtcars, aes(mpg)) + geom_histogram(binwidth = 2)
# two plots side by side, one underneath
(p1 | p2) / p3
Layout with plot_layout()
According to the layout guide, plot_layout() accepts ncol, widths, heights (relative numbers or a vector of units), design, guides, and the axes and axis_titles options (which can be set to 'collect').
p1 + p2 + p3 + plot_layout(ncol = 3)
p1 + p2 + plot_layout(widths = c(2, 1))
p1 + plot_spacer() + p2
plot_spacer() inserts an empty cell. For irregular grids, design takes a text string in which each letter is a plot (assigned in the order the plots were added) and # marks an empty cell; the guide’s example is:
layout <- "
##BBBB
AACCDD
##CCDD
"
p1 + p2 + p3 + p4 + plot_layout(design = layout)
Alternatively, area(t, l, b, r) defines each plot’s rectangle by top, left, bottom and right position, and wrap_plots() takes plots plus a design.
Panel tags, titles and a shared legend
(p1 | p2) / p3 +
plot_layout(guides = 'collect') +
plot_annotation(
title = 'Fuel economy and weight',
tag_levels = 'A'
)
guides = 'collect' gathers legends into one (the default is 'auto'; 'keep' leaves them with each plot). plot_annotation() takes title, subtitle, caption and tag_levels, where tag_levels accepts '1', 'A', 'a', 'I' or 'i', or a vector such as c('A', '1') for sub-tagging. tag_prefix, tag_sep and tag_suffix adjust the label text.
Output and how to read it
The result of combining plots is a single patchwork object that draws as one graphic in the active graphics device. Each panel keeps its own axes, and patchwork aligns the panels across the figure. With tag_levels = 'A', panels are labelled in the order they were added, so the order of +, | and / in your expression determines which panel is A, B and C. Check that your manuscript text refers to panels in that order.
Troubleshooting
- Title or tags appear on the wrong level. The annotation guide states that annotations apply only to the top-level patchwork. A nested group needs
wrap_elements(), which, per the same guide, breaks alignment for that group. - Theme change affects only some elements. Using
&applies a modification to all subplots, for examplepatchwork & theme(text = element_text('mono')), whileplot_annotation(theme = ...)styles the patchwork itself. - Several repeated legends. Use
plot_layout(guides = 'collect'). - Install fails on dependencies. The CRAN page lists the minimum versions of ggplot2, gtable and rlang; update those packages first.
- Grid shape. Set
ncolinplot_layout(), or usedesignfor exact placement.
Free alternatives
The CRAN description of patchwork names two other approaches for arranging ggplots. This table lists only what that description states.
| Package | Relationship to patchwork | Source |
|---|---|---|
| patchwork | Combines ggplots with operators such as +, | and / |
CRAN and package site |
| gridExtra | Named on the patchwork CRAN page as another approach | CRAN, patchwork description |
| cowplot | Named on the patchwork CRAN page as another approach | CRAN, patchwork description |
FAQ
What does patchwork do in R?
It combines multiple ggplot2 plots into one graphic, using operators to place and nest them and keeping the panels aligned.
How do I put two ggplots side by side?
Use p1 | p2. To stack them use p1 / p2; to do both, (p1 | p2) / p3.
How do I label panels A, B, C?
Add plot_annotation(tag_levels = 'A') to the top-level patchwork.
How do I share one legend?
Add plot_layout(guides = 'collect').
Is patchwork free?
It is released under an MIT + file LICENSE according to its CRAN page.
Sources
- patchwork package site, read 2026-11-08
- patchwork on CRAN (version 1.3.2), read 2026-11-08
- Controlling layouts, read 2026-11-08
- Annotation, read 2026-11-08







