Multiple Methods for Side-by-Side Plot Layouts with ggplot2

Nov 07, 2025 · Programming · 14 views · 7.8

Keywords: ggplot2 | side-by-side plots | gridExtra | cowplot | patchwork | data visualization

Abstract: This article comprehensively explores three main approaches for creating side-by-side plot layouts in R using ggplot2: the grid.arrange function from gridExtra package, the plot_grid function from cowplot package, and the + operator from patchwork package. Through comparative analysis of their strengths and limitations, along with practical code examples, it demonstrates how to flexibly choose appropriate methods to meet various visualization needs, including basic layouts, label addition, theme unification, and complex compositions.

Introduction

In data visualization, it is often necessary to display multiple charts side-by-side for comparative analysis or to present data insights from different perspectives. While base R provides par(mfrow=c(1,2)) for this purpose, the ggplot2 ecosystem requires specialized extension packages to achieve similar functionality. This article systematically introduces three mainstream implementation methods.

Basic Layout with gridExtra Package

The grid.arrange() function from the gridExtra package is one of the earliest widely used multi-plot layout tools. Its basic usage is straightforward:

library(gridExtra)
library(ggplot2)

# Create two example plots
plot1 <- ggplot(mpg, aes(x = displ, y = hwy)) + geom_point()
plot2 <- ggplot(mpg, aes(x = class)) + geom_bar()

# Display plots side by side
grid.arrange(plot1, plot2, ncol = 2)

This approach is particularly suitable for combining plots based on different datasets, as it doesn't require data reshaping. For output to files, traditional graphics device methods can be used:

pdf("multi_plot.pdf")
grid.arrange(plot1, plot2, ncol = 2)
dev.off()

Alternatively, combine arrangeGrob() with ggsave():

combined_plot <- arrangeGrob(plot1, plot2, ncol = 2)
ggsave("multi_plot.pdf", combined_plot)

Enhanced Layout with cowplot Package

The cowplot package provides the plot_grid() function, which adds practical features like automatic labeling and size optimization on top of basic layout capabilities:

library(cowplot)

# Create two plots with different geometries
scatter_plot <- ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width)) + 
  geom_point(aes(color = Species)) + theme_bw()

density_plot <- ggplot(iris, aes(x = Sepal.Length, fill = Species)) + 
  geom_density(alpha = 0.5) + theme_bw()

# Display side by side with automatic labels
combined <- plot_grid(scatter_plot, density_plot, labels = "AUTO", ncol = 2)

plot_grid() returns a standard ggplot object that can be directly saved using ggsave():

ggsave("labeled_plots.pdf", combined)

Or use cowplot's save_plot() function, which automatically calculates appropriate image dimensions:

save_plot("optimized_plot.pdf", combined, ncol = 2)

Note that cowplot modifies ggplot2's default theme, which can be avoided through the following approaches:

# Method 1: Explicitly set theme
plot1 <- ggplot(iris, aes(x = Species, y = Sepal.Length)) + 
  geom_boxplot() + theme_gray()

# Method 2: Restore default theme
theme_set(theme_gray())

# Method 3: Use namespace calling
cowplot::plot_grid(plot1, plot2, labels = "AUTO")

Flexible Layout with patchwork Package

The patchwork package provides a more intuitive and flexible layout approach by extending the concept of the + operator:

library(patchwork)

# Create multiple plots
p1 <- ggplot(mpg, aes(x = displ, y = hwy)) + geom_point()
p2 <- ggplot(mpg, aes(x = class)) + geom_bar()
p3 <- ggplot(mpg, aes(x = hwy, fill = drv)) + geom_density(alpha = 0.5)

# Basic side-by-side layout
basic_layout <- p1 + p2 + p3

Layout can be precisely controlled using plot_layout():

# Specify number of columns
custom_layout <- p1 + p2 + p3 + plot_layout(ncol = 2)

# Use operators for single row/column layout
row_layout <- p1 | p2  # Single row layout
col_layout <- p1 / p2  # Single column layout

patchwork also supports complex nested layouts:

complex_layout <- p3 | (p2 / (p1 | p4))

Unified Legend and Theme Management

In multi-plot layouts, unified handling of legends and theme styles is often necessary. patchwork offers convenient solutions:

# Collect and unify legends
unified_legend <- p1 + p2 + p3 + plot_layout(ncol = 2, guides = "collect")

# Apply consistent theme
consistent_theme <- p1 + p2 & theme_minimal()

# Set uniform axis ranges
consistent_scale <- p1 + p2 & scale_y_continuous(limits = c(0, 50))

Adding Global Annotations and Labels

For scientific publications, it's common to add unified titles and subplot labels to combined charts:

# Add global title and description
annotated_plot <- p1 + p2 + plot_annotation(
  title = "Comparative Analysis of Automotive Performance Metrics",
  caption = "Data source: mpg dataset"
)

# Automatically add subplot labels
tagged_plot <- p1 | p2 | p3 + plot_annotation(tag_levels = "A")

Method Comparison and Selection Guidelines

Each of the three methods has distinct advantages: grid.arrange() is the most basic and stable, suitable for simple side-by-side requirements; plot_grid() excels in label handling and size optimization, making it ideal for academic publishing; patchwork provides the most flexible layout control and unified theme management, perfect for complex visualization projects.

In practical applications, selection should be based on specific needs: for simple 2-3 plot side-by-side arrangements, grid.arrange() is sufficient; when publication-quality labels and formatting are required, choose plot_grid(); and for complex layouts with unified style management, patchwork is the optimal choice.

Conclusion

The ggplot2 ecosystem offers multiple powerful multi-plot layout tools that can accommodate various visualization needs ranging from simple comparisons to complex compositions. Mastering these tools can significantly enhance the efficiency and quality of data visualization, providing strong support for data analysis and result presentation.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.