To arrange multiple ggplot2 graphs on the same page, the standard R functions - par() and layout() - cannot be used.
The basic solution is to use the gridExtra R package, which comes with the following functions:
grid.arrange() and arrangeGrob() to arrange multiple ggplots on one page
marrangeGrob() for arranging multiple ggplots over multiple pages.
However, these functions makes no attempt at aligning the plot panels; instead, the plots are simply placed into the grid as they are, and so the axes are not aligned.
If axis alignment is required, you can switch to the cowplot package, which include the function plot_grid() with the argument align. However, the cowplot package doesn’t contain any solution for multi-pages layout. Therefore, we provide the function ggarrange() [in ggpubr], a wrapper around the plot_grid() function, to arrange multiple ggplots over multiple pages. It can also create a common unique legend for multiple plots.
This article will show you, step by step, how to combine multiple ggplots on the same page, as well as, over multiple pages, using helper functions available in the following R package: ggpubr R package, cowplot and gridExtra. We’ll also describe how to export the arranged plots to a file.
Related articles:
Bar Plots and Modern Alternatives
Facilitating Exploratory Data Visualization: Application to TCGA Genomic Data
Add P-values and Significance Levels to ggplots
Contents:
Prerequisites
Create some plots
Arrange on one page
Annotate the arranged figure
Align plot panels
Change column/row span of a plot
Use common legend for combined ggplots
Scatter plot with marginal density plots
Mix table, text and ggplot2 graphs
Insert a graphical element inside a ggplot
Arrange over multiple pages
Nested layout with ggarrange()
Export plots
Acknoweledgment
Infos
Prerequisites
Required R package
You need to install the R package ggpubr (version __= 0.1.3), to easily create ggplot2-based publication ready plots.
We recommend to install the latest developmental version from GitHub as follow:
if(!require(devtools)) install.packages(&quot;devtools&quot;)
devtools::install_github(&quot;kassambara/ggpubr&quot;)
If installation from Github failed, then try to install from CRAN as follow:
install.packages(&quot;ggpubr&quot;)
Note that, the installation of ggpubr will install the gridExtra and the cowplot package; so you don’t need to re-install them.
Load ggpubr:
library(ggpubr)
Demo data sets
Data: ToothGrowth and mtcars data sets.
# ToothGrowth
data(&quot;ToothGrowth&quot;)
head(ToothGrowth)
len supp dose
1 4.2 VC 0.5
2 11.5 VC 0.5
3 7.3 VC 0.5
4 5.8 VC 0.5
5 6.4 VC 0.5
6 10.0 VC 0.5
# mtcars data(&quot;mtcars&quot;)
mtcars$name name wt mpg cyl
Mazda RX4 Mazda RX4 2.620 21.0 6
Mazda RX4 Wag Mazda RX4 Wag 2.875 21.0 6
Datsun 710 Datsun 710 2.320 22.8 4
Hornet 4 Drive Hornet 4 Drive 3.215 21.4 6
Hornet Sportabout Hornet Sportabout 3.440 18.7 8
Valiant Valiant 3.460 18.1 6
Create some plots
Here, we’ll use ggplot2-based plotting functions available in ggpubr. You can use any ggplot2 functions to create the plots that you want for arranging them later.
We’ll start by creating 4 different plots:
Box plots and dot plots using the ToothGrowth data set
Bar plots and scatter plots using the mtcars data set
You’ll learn how to combine these plots in the next sections using specific functions.
Create a box plot and a dot plot:
# Box plot (bp)
bxp Arrange multiple ggplots on the same page
Create an ordered bar plot and a scatter plot:
Create ordered bar plots. Change the fill color by the grouping variable “cyl”. Sorting will be done globally, but not by groups.
# Bar plot (bp)
bp Arrange multiple ggplots on the same page
Arrange on one page
To arrange multiple ggplots on one single page, we’ll use the function ggarrange()[in ggpubr], which is a wrapper around the function plot_grid() [in cowplot package]. Compared to the standard function plot_grid(), ggarange() can arrange multiple ggplots over multiple pages.
ggarrange(bxp, dp, bp + rremove(&quot;x.text&quot;), labels = c(&quot;A&quot;, &quot;B&quot;, &quot;C&quot;),
ncol = 2, nrow = 2)
Arrange multiple ggplots on the same page
Alternatively, you can also use the function plot_grid() [in cowplot]:
library(&quot;cowplot&quot;)
plot_grid(bxp, dp, bp + rremove(&quot;x.text&quot;), labels = c(&quot;A&quot;, &quot;B&quot;, &quot;C&quot;),
ncol = 2, nrow = 2)
or, the function grid.arrange() [in gridExtra]:
library(&quot;gridExtra&quot;)
grid.arrange(bxp, dp, bp + rremove(&quot;x.text&quot;), ncol = 2, nrow = 2)
Annotate the arranged figure
R function: annotate_figure() [in ggpubr].
figure Arrange multiple ggplots on the same page
Note that, the function annotate_figure() supports any ggplots.
Align plot panels
A real use case is, for example, when plotting survival curves with the risk table placed under the main plot.
To illustrate this case, we’ll use the survminer package. First, install it using install.packages(“survminer”), then type this:
# Fit survival curves
library(survival)
fit [1] &quot;plot&quot; &quot;table&quot; &quot;data.survplot&quot; &quot;data.survtable&quot;
ggsurv is a list including the components:
plot: survival curves
table: the risk table plot
You can arrange the survival plot and the risk table as follow:
ggarrange(ggsurv$plot, ggsurv$table, heights = c(2, 0.7),
ncol = 1, nrow = 2)
Arrange multiple ggplots on the same page
It can be seen that the axes of the survival plot and the risk table are not aligned vertically. To align them, specify the argument align as follow.
ggarrange(ggsurv$plot, ggsurv$table, heights = c(2, 0.7),
ncol = 1, nrow = 2, align = &quot;v&quot;)
Arrange multiple ggplots on the same page
Change column/row span of a plot
Use ggpubr R package
We’ll use nested ggarrange() functions to change column/row span of plots.
For example, using the R code below:
the scatter plot (sp) will live in the first row and spans over two columns
the box plot (bxp) and the dot plot (dp) will be first arranged and will live in the second row with two different columns
ggarrange(sp, # First row with scatter plot
ggarrange(bxp, dp, ncol = 2, labels = c(&quot;B&quot;, &quot;C&quot;)), # Second row with box and dot plots
nrow = 2, labels = &quot;A&quot; # Labels of the scatter plot
) Arrange multiple ggplots on the same page
Use cowplot R package
The combination of the functions ggdraw() + draw_plot() + draw_plot_label() [in cowplot] can be used to place graphs at particular locations with a particular size.
ggdraw(). Initialize an empty drawing canvas:
ggdraw()
Note that, by default, coordinates run from 0 to 1, and the point (0, 0) is in the lower left corner of the canvas (see the figure below).
draw_plot(). Places a plot somewhere onto the drawing canvas:
draw_plot(plot, x = 0, y = 0, width = 1, height = 1)
plot: the plot to place (ggplot2 or a gtable)
x, y: The x/y location of the lower left corner of the plot.
width, height: the width and the height of the plot
draw_plot_label(). Adds a plot label to the upper left corner of a graph. It can handle vectors of labels with associated coordinates.
draw_plot_label(label, x = 0, y = 1, size = 16, ...)
label: a vector of labels to be drawn
x, y: Vector containing the x and y position of the labels, respectively.
size: Font size of the label to be drawn
For example, you can combine multiple plots, with particular locations and different sizes, as follow:
library(&quot;cowplot&quot;)
ggdraw() +
draw_plot(bxp, x = 0, y = .5, width = .5, height = .5) +
draw_plot(dp, x = .5, y = .5, width = .5, height = .5) +
draw_plot(bp, x = 0, y = 0, width = 1, height = 0.5) +
draw_plot_label(label = c(&quot;A&quot;, &quot;B&quot;, &quot;C&quot;), size = 15,
x = c(0, 0.5, 0), y = c(1, 1, 0.5))
Arrange multiple ggplots on the same page
Use gridExtra R package
The function arrangeGrop() [in gridExtra] helps to change the row/column span of a plot.
For example, using the R code below:
the scatter plot (sp) will live in the first row and spans over two columns
the box plot (bxp) and the dot plot (dp) will live in the second row with two plots in two different columns
library(&quot;gridExtra&quot;)
grid.arrange(sp, # First row with one plot spaning over 2 columns
arrangeGrob(bxp, dp, ncol = 2), # Second row with 2 plots in 2 different columns
nrow = 2) # Number of rows
Arrange multiple ggplots on the same page
It’s also possible to use the argument layout_matrix in the grid.arrange() function, to create a complex layout.
In the R code below layout_matrix is a 2x2 matrix (2 columns and 2 rows). The first row is all 1s, that’s where the first plot lives, spanning the two columns; the second row contains plots 2 and 3 each occupying one column.
grid.arrange(bp, # bar plot spaning two columns
bxp, sp, # box plot and scatter plot
ncol = 2, nrow = 2, layout_matrix = rbind(c(1,1), c(2,3)))
Arrange multiple ggplots on the same page
Note that, it’s also possible to annotate the output of the grid.arrange() function using the helper function draw_plot_label() [in cowplot].
To easily annotate the grid.arrange() / arrangeGrob() output (a gtable), you should first transform it to a ggplot using the function as_ggplot() [in ggpubr ]. Next you can annotate it using the function draw_plot_label() [in cowplot].
library(&quot;gridExtra&quot;)
library(&quot;cowplot&quot;)
# Arrange plots using arrangeGrob
# returns a gtable (gt)
gt Arrange multiple ggplots on the same page
In the above R code, we used arrangeGrob() instead of grid.arrange().
Note that, the main difference between these two functions is that, grid.arrange() draw automatically the output of the arranged plots.
As we want to annotate the arranged plots before drawing it, the function arrangeGrob() is preferred in this case.
Use grid R package
The grid R package can be used to create a complex layout with the help of the function grid.layout(). It provides also the helper function viewport() to define a region or a viewport on the layout. The function print() is used to place plots in a specified region.
The different steps can be summarized as follow :
Create plots : p1, p2, p3, ….
Move to a new page on a grid device using the function grid.newpage()
Create a layout 2X2 - number of columns = 2; number of rows = 2
Define a grid viewport : a rectangular region on a graphics device
Print a plot into the viewport
library(grid)
# Move to a new page
grid.newpage()
# Create layout : nrow = 3, ncol = 2
pushViewport(viewport(layout = grid.layout(nrow = 3, ncol = 2)))
# A helper function to define a region on the layout
define_region Arrange multiple ggplots on the same page
Use common legend for combined ggplots
To place a common unique legend in the margin of the arranged plots, the function ggarrange() [in ggpubr] can be used with the following arguments:
common.legend = TRUE: place a common legend in a margin
legend: specify the legend position. Allowed values include one of c(“top”, “bottom”, “left”, “right”)
ggarrange(bxp, dp, labels = c(&quot;A&quot;, &quot;B&quot;),
common.legend = TRUE, legend = &quot;bottom&quot;)
Arrange multiple ggplots on the same page
Scatter plot with marginal density plots
# Scatter plot colored by groups (&quot;Species&quot;)
sp Arrange multiple ggplots on the same page
Mix table, text and ggplot2 graphs
In this section, we’ll show how to plot a table and text alongside a chart. The iris data set will be used.
We start by creating the following plots:
a density plot of the variable “Sepal.Length”. R function: ggdensity() [in ggpubr]
a plot of the summary table containing the descriptive statistics (mean, sd, … ) of Sepal.Length.
R function for computing descriptive statistics: desc_statby() [in ggpubr].
R function to draw a textual table: ggtexttable() [in ggpubr].
a plot of a text paragraph. R function: ggparagraph() [in ggpubr].
We finish by arranging/combining the three plots using the function ggarrange() [in ggpubr]
# Density plot of &quot;Sepal.Length&quot;
#::::::::::::::::::::::::::::::::::::::
density.p Arrange multiple ggplots on the same page
Insert a graphical element inside a ggplot
The function annotation_custom() [in ggplot2] can be used for adding tables, plots or other grid-based elements within the plotting area of a ggplot. The simplified format is :
annotation_custom(grob, xmin, xmax, ymin, ymax)
grob: the external graphical element to display
xmin, xmax : x location in data coordinates (horizontal location)
ymin, ymax : y location in data coordinates (vertical location)
Place a table within a ggplot
We’ll use the plots - density.p and stable.p - created in the previous section (@ref(mix-table-text-and-ggplot)).
density.p + annotation_custom(ggplotGrob(stable.p),
xmin = 5.5, ymin = 0.7,
xmax = 8)
Arrange multiple ggplots on the same page
Place a box plot within a ggplot
Create a scatter plot of y = “Sepal.Width” by x = “Sepal.Length” using the iris data set. R function ggscatter() [ggpubr]
Create separately the box plot of x and y variables with transparent background. R function: ggboxplot() [ggpubr].
Transform the box plots into graphical objects called a “grop” in Grid terminology. R function ggplotGrob() [ggplot2].
Place the box plot grobs inside the scatter plot. R function: annotation_custom() [ggplot2].
As the inset box plot overlaps with some points, a transparent background is used for the box plots.
# Scatter plot colored by groups (&quot;Species&quot;)
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
sp Arrange multiple ggplots on the same page
Add background image to ggplot2 graphs
Import the background image. Use either the function readJPEG() [in jpeg package] or the function readPNG() [in png package] depending on the format of the background image.
To test the example below, make sure that the png package is installed. You can install it using install.packages(“png”) R command.
# Import the image
img.file Combine a ggplot with the background image. R function: background_image() [in ggpubr].
library(ggplot2)
library(ggpubr)
ggplot(iris, aes(Species, Sepal.Length))+
background_image(img)+
geom_boxplot(aes(fill = Species), color = &quot;white&quot;)+
fill_palette(&quot;jco&quot;)
Arrange multiple ggplots on the same page
Change box plot fill color transparency by specifying the argument alpha. Value should be in [0, 1], where 0 is full transparency and 1 is no transparency.
library(ggplot2)
library(ggpubr)
ggplot(iris, aes(Species, Sepal.Length))+
background_image(img)+
geom_boxplot(aes(fill = Species), color = &quot;white&quot;, alpha = 0.5)+
fill_palette(&quot;jco&quot;)
Arrange multiple ggplots on the same page
Another example, overlaying the France map and a ggplot2:
mypngfile Arrange multiple ggplots on the same page
Arrange over multiple pages
If you have a long list of ggplots, say n = 20 plots, you may want to arrange the plots and to place them on multiple pages. With 4 plots per page, you need 5 pages to hold the 20 plots.
The function ggarrange() [in ggpubr] provides a convenient solution to arrange multiple ggplots over multiple pages. After specifying the arguments nrow and ncol, the function ggarrange() computes automatically the number of pages required to hold the list of the plots. It returns a list of arranged ggplots.
For example the following R code,
multi.page returns a list of two pages with two plots per page. You can visualize each page as follow:
multi.page[[1]] # Visualize page 1
multi.page[[2]] # Visualize page 2
You can also export the arranged plots to a pdf file using the function ggexport() [in ggpubr]:
ggexport(multi.page, filename = &quot;multi.page.ggplot2.pdf&quot;)
PDF file: Multi.page.ggplot2
Note that, it’s also possible to use the function marrangeGrob() [in gridExtra] to create a multi-pages output.
library(gridExtra)
res Nested layout with ggarrange()
We’ll arrange the plot created in section (@ref(mix-table-text-and-ggplot)) and (@ref(create-some-plots)).
p1 Arrange multiple ggplots on the same page
Export plots
R function: ggexport() [in ggpubr].
First, create a list of 4 ggplots corresponding to the variables Sepal.Length, Sepal.Width, Petal.Length and Petal.Width in the iris data set.
plots Next, you can export individual plots to a file (pdf, eps or png) (one plot per page). It’s also possible to arrange the plots (2 plot per page) when exporting them.
Export individual plots to a pdf file (one plot per page):
ggexport(plotlist = plots, filename = &quot;test.pdf&quot;)
Arrange and export. Specify nrow and ncol to display multiple plots on the same page:
ggexport(plotlist = plots, filename = &quot;test.pdf&quot;,
nrow = 2, ncol = 1)
Acknoweledgment
We sincerely thank all developers for their efforts behind the packages that ggpubr depends on, namely:
Baptiste Auguie (2016). gridExtra: Miscellaneous Functions for “Grid” Graphics. R package version 2.2.1. https://CRAN.R-project.org/package=gridExtra
Claus O. Wilke (2016). cowplot: Streamlined Plot Theme and Plot Annotations for ‘ggplot2’. R package version 0.7.0. https://CRAN.R-project.org/package=cowplot
H. Wickham. ggplot2: Elegant Graphics for Data Analysis. Springer-Verlag New York, 2009.
Infos
This analysis has been performed using R software (ver. 3.3.2) and ggpubr (ver. 0.1.4.999).