Ggplot2 - Easy Way To Mix Multiple Graphs On The Same Page - Articles - STHDA
Ggplot2 - Easy Way To Mix Multiple Graphs On The Same Page - Articles - STHDA
Licence:
Search...
Home Basics Data Visualize Analyze Resources Our Products Support About
Home / Articles / Data Visualization / ggpubr: Publication Ready Plots / ggplot2 - Easy Way to Mix Multiple Graphs on The Same Page
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 func-
tions 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:
Contents:
Prerequisites
Required R package
Demo data sets
Prerequisites
Required R package
You need to install the R package ggpubr (version >= 0.1.3), to easily create ggplot2-based publication ready plots.
if(!require(devtools)) install.packages("devtools")
devtools::install_github("kassambara/ggpubr")
If installation from Github failed, then try to install from CRAN as follow:
install.packages("ggpubr")
Note that, the installation of ggpubr will automatically install the gridExtra and the cowplot package; so you don’t need to re-install them.
Load ggpubr:
library(ggpubr)
# ToothGrowth
data("ToothGrowth")
head(ToothGrowth)
# mtcars
data("mtcars")
mtcars$name <- rownames(mtcars)
mtcars$cyl <- as.factor(mtcars$cyl)
head(mtcars[, c("name", "wt", "mpg", "cyl")])
You’ll learn how to combine these plots in the next sections using specific functions.
library("cowplot")
plot_grid(bxp, dp, bp + rremove("x.text"),
labels = c("A", "B", "C"),
ncol = 2, nrow = 2)
or, the function grid.arrange() [in gridExtra]:
library("gridExtra")
grid.arrange(bxp, dp, bp + rremove("x.text"),
ncol = 2, nrow = 2)
To illustrate this case, we’ll use the survminer package. First, install it using install.packages(“survminer”), then type this:
You can arrange the survival plot and the risk table as follow:
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("B", "C")), # Second row with box and dot plots
nrow = 2,
labels = "A" # Labels of the scatter plot
)
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()
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_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, ...)
For example, you can combine multiple plots, with particular locations and different sizes, as follow:
library("cowplot")
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("A", "B", "C"), size = 15,
x = c(0, 0.5, 0), y = c(1, 1, 0.5))
Use gridExtra R package
The function arrangeGrop() [in gridExtra] helps to change the row/column span of a plot.
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("gridExtra")
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
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.
library("gridExtra")
library("cowplot")
# Arrange plots using arrangeGrob
# returns a gtable (gt)
gt <- arrangeGrob(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)))
# Add labels to the arranged plots
p <- as_ggplot(gt) + # transform to a ggplot
draw_plot_label(label = c("A", "B", "C"), size = 15,
x = c(0, 0, 0.5), y = c(1, 0.5, 0.5)) # Add labels
p
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.
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 <- function(row, col){
viewport(layout.pos.row = row, layout.pos.col = col)
}
# Arrange the plots
print(sp, vp = define_region(row = 1, col = 1:2)) # Span over two columns
print(bxp, vp = define_region(row = 2, col = 1))
print(dp, vp = define_region(row = 2, col = 2))
print(bp + rremove("x.text"), vp = define_region(row = 3, col = 1:2))
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:
density.p + annotation_custom(ggplotGrob(stable.p),
xmin = 5.5, ymin = 0.7,
xmax = 8)
Place a box plot within a ggplot
1. Create a scatter plot of y = “Sepal.Width” by x = “Sepal.Length” using the iris data set. R function ggscatter() [ggpubr]
2. Create separately the box plot of x and y variables with transparent background. R function: ggboxplot() [ggpubr].
3. Transform the box plots into graphical objects called a “grop” in Grid terminology. R function ggplotGrob() [ggplot2].
4. 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 ("Species")
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
sp <- ggscatter(iris, x = "Sepal.Length", y = "Sepal.Width",
color = "Species", palette = "jco",
size = 3, alpha = 0.6)
# Create box plots of x/y variables
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# Box plot of the x variable
xbp <- ggboxplot(iris$Sepal.Length, width = 0.3, fill = "lightgray") +
rotate() +
theme_transparent()
# Box plot of the y variable
ybp <- ggboxplot(iris$Sepal.Width, width = 0.3, fill = "lightgray") +
theme_transparent()
# Create the external graphical objects
# called a "grop" in Grid terminology
xbp_grob <- ggplotGrob(xbp)
ybp_grob <- ggplotGrob(ybp)
# Place box plots inside the scatter plot
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
xmin <- min(iris$Sepal.Length); xmax <- max(iris$Sepal.Length)
ymin <- min(iris$Sepal.Width); ymax <- max(iris$Sepal.Width)
yoffset <- (1/15)*ymax; xoffset <- (1/15)*xmax
# Insert xbp_grob inside the scatter plot
sp + annotation_custom(grob = xbp_grob, xmin = xmin, xmax = xmax,
ymin = ymin-yoffset, ymax = ymin+yoffset) +
# Insert ybp_grob inside the scatter plot
annotation_custom(grob = ybp_grob,
xmin = xmin-xoffset, xmax = xmin+xoffset,
ymin = ymin, ymax = ymax)
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.
library(ggplot2)
library(ggpubr)
ggplot(iris, aes(Species, Sepal.Length))+
background_image(img)+
geom_boxplot(aes(fill = Species), color = "white")+
fill_palette("jco")
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 = "white", alpha = 0.5)+
fill_palette("jco")
The function ggarrange() [in ggpubr] provides a convenient solution to arrange multiple ggplots over multiple pages. After specifying the argu-
ments 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.
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]:
library(gridExtra)
res <- marrangeGrob(list(bxp, dp, bp, sp), nrow = 1, ncol = 2)
# Export to a pdf file
ggexport(res, filename = "multi.page.ggplot2.pdf")
# Visualize interactively
res
Nested layout with ggarrange()
We’ll arrange the plot created in section (@ref(mix-table-text-and-ggplot)) and (@ref(create-some-plots)).
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.
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 ex-
porting them.
Arrange and export. Specify nrow and ncol to display multiple plots on the same page:
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.
0 Note
Enjoyed this article? Give us 5 stars (just above this text block)! Reader needs to be STHDA member for voting. I’d be very
grateful if you’d help it spread by emailing it to a friend, or sharing it on Twitter, Facebook or Linked In.
Show me some love with the like buttons below... Thank you and please don't forget to share and comment below!!
Machine Learning Essentials: Practical Practical Guide to Cluster Analysis in R Practical Guide to Principal Component
Guide in R Methods in R
More books on R and data science
R Graphics Essentials for Great Data Visual- Network Analysis and Visualization in R
ization
This section contains best data science and self-development resources to help you on your path.
Coursera - Online Courses and Specialization
Data science
Course: Machine Learning: Master the Fundamentals by Standford
Specialization: Data Science by Johns Hopkins University
Specialization: Python for Everybody by University of Michigan
Courses: Build Skills for a Top Job in any Industry by Coursera
Specialization: Master Machine Learning Fundamentals by University of Washington
Specialization: Statistics with R by Duke University
Specialization: Software Development in R by Johns Hopkins University
Specialization: Genomic Data Science by Johns Hopkins University
Trending Courses
The Science of Well-Being by Yale University
Google IT Support Professional by Google
Python for Everybody by University of Michigan
IBM Data Science Professional Certificate by IBM
Business Foundations by University of Pennsylvania
Introduction to Psychology by Yale University
Excel Skills for Business by Macquarie University
Psychological First Aid by Johns Hopkins University
Graphic Design by Cal Arts
Others
R for Data Science: Import, Tidy, Transform, Visualize, and Model Data by Hadley Wickham & Garrett Grolemund
Hands-On Machine Learning with Scikit-Learn, Keras, and TensorFlow: Concepts, Tools, and Techniques to Build Intelligent Systems by Aure-
lien Géron
Practical Statistics for Data Scientists: 50 Essential Concepts by Peter Bruce & Andrew Bruce
Hands-On Programming with R: Write Your Own Functions And Simulations by Garrett Grolemund & Hadley Wickham
An Introduction to Statistical Learning: with Applications in R by Gareth James et al.
Deep Learning with R by François Chollet & J.J. Allaire
Deep Learning with Python by François Chollet
Member
This is great Kassambara. A lot of interesting ways to present my data. I was just wondering if you had a preference, cowplot or
grid. Is one more robust than the other?
Thanks again!
Jeremy
#848
Very nice. Just a comment on the scatter plot with the inserted box plots: the box plots are not placed correctly. Both are closer
to the origin than they should be. How did this happen and how can it be corrected?
#749
Very nice job, with excellent attention to detail. I picked up several bits that will make me a much better user of ggplot. Keep up
the great work. Cheers, Bob
#710
#657
Nice walk through. Is there any way to change the size of a table inserted into a ggplot?
I have a ggplot with a geom_col and I want to insert a table in the upper right corner, but the table is huge compared to the plot
and I can't figure out how to reduce its size.
#602
Thank you very much for putting this together! Very useful
#526
#384
#372
#351
kassambara 12/18/2017 at 04h59
Administrator
#327
It would be nice to be able to read the article but the page keeps scrolling to the google ad making it impossible.... (using
Chrome on Mac OS X).
#326
Sign in
Login
Login
Password
Password
Auto connect
Sign in
Register
Forgotten password
Welcome!
Want to Learn More on R Programming and Data Science?
Follow us by Email
Subscribe
by FeedBurner
factoextra
survminer
ggpubr
ggcorrplot
fastqcr
Our Books
R Graphics Essentials for Great Data Visualization: 200 Practical Examples You Want to Know for Data Science
NEW!!
Practical Guide to Cluster Analysis in R
D Plots in R
R-Bloggers
Newsletter Email
Boosted by PHPBoost