<p><div><div><div><div data-show-faces="false" data-height="21" data-width="100" data-layout="button_count" data-send="true" data-href="https://www.r-bloggers.com/beyond-basic-r-plotting-with-ggplot2-and-multiple-plots-in-one-figure/"></div></div><div></div></div><div></div></div>
<div>
(This article was first published on <strong><a href="https://owi.usgs.gov/blog/beyond-basic-plotting/"> The USGS OWI blog </a></strong>, and kindly contributed to <a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers)</a> </div>
<p>R can create almost any plot imaginable and as with most things in R if you don’t know where to start, try Google. The <a rel="nofollow" href="https://owi.usgs.gov/R/training-curriculum/intro-curriculum" target="_blank">Introduction to R curriculum</a> summarizes some of the most used plots, but cannot begin to expose people to the breadth of plot options that exist.There are existing resources that are great references for plotting in R:</p>
<p>In base R:</p>
<ul>
<li><a rel="nofollow" href="https://www.r-bloggers.com/how-to-plot-a-graph-in-r/" target="_blank">Breakdown of how to create a plot</a> from R-bloggers</li>
<li><a rel="nofollow" href="https://flowingdata.com/2012/12/17/getting-started-with-charts-in-r/" target="_blank">Another blog breaking down basic plotting</a> from FlowingData</li>
<li><a rel="nofollow" href="https://www.cyclismo.org/tutorial/R/plotting.html" target="_blank">Basic plots</a> (histograms, boxplots, scatter plots, QQ plots) from University of Georgia</li>
<li><a rel="nofollow" href="https://www.cyclismo.org/tutorial/R/intermediatePlotting.html" target="_blank">Intermediate plots</a> (error bars, density plots, bar charts, multiple windows, saving to a file, etc) from University of Georgia</li>
</ul>
<p>In ggplot2:</p>
<ul>
<li><a rel="nofollow" href="http://ggplot2.tidyverse.org/" target="_blank">ggplot2 homepage</a></li>
<li><a rel="nofollow" href="https://www.youtube.com/watch?v=rsG-GgR0aEY" target="_blank">ggplot2 video tutorial</a></li>
<li><a rel="nofollow" href="http://r-statistics.co/Complete-Ggplot2-Tutorial-Part1-With-R-Code.html" target="_blank">Website with everything you want to know about ggplot2</a> by Selva Prabhakaran</li>
<li><a rel="nofollow" href="http://www.cookbook-r.com/Graphs/" target="_blank">R graphics cookbook site</a></li>
<li><a rel="nofollow" href="https://www.rstudio.com/wp-content/uploads/2015/03/ggplot2-cheatsheet.pdf" target="_blank">ggplot2 cheatsheet</a></li>
<li><a rel="nofollow" href="http://ggplot2.tidyverse.org/reference/" target="_blank">ggplot2 reference guide</a></li>
</ul>
<p>In the <a rel="nofollow" href="https://owi.usgs.gov/R/training-curriculum/intro-curriculum" target="_blank">Introduction to R</a> class, we have switched to teaching ggplot2 because it works nicely with other tidyverse packages (dplyr, tidyr), and can create interesting and powerful graphics with little code. While <code>ggplot2</code> has many useful features, this blog post will explore how to create figures with multiple <code>ggplot2</code> plots.</p>
<p>You may have already heard of ways to put multiple R plots into a single figure – specifying <code>mfrow</code> or <code>mfcol</code> arguments to <code>par</code>, <code>split.screen</code>, and <code>layout</code> are all ways to do this. However, there are other methods to do this that are optimized for <code>ggplot2</code> plots.</p>
<h2>Multiple plots in one figure using ggplot2 and facets</h2>
<p>When you are creating multiple plots and they share axes, you should consider using facet functions from ggplot2 (<code>facet_grid</code>, <code>facet_wrap</code>). You write your <code>ggplot2</code> code as if you were putting all of the data onto one plot, and then you use one of the faceting functions to specify how to slice up the graph.</p>
<p>Let’s start by considering a set of graphs with a common x axis. You have a data.frame with four columns: Date, site_no, parameter, and value. You want three different plots in the same figure – a timeseries for each of the parameters with different colored symbols for the different sites. Sounds like a lot, but facets can make this very simple. First, setup your ggplot code as if you aren’t faceting.</p>
<p>We will download USGS water data for use in this example from the USGS National Water Information System (NWIS) using the <code>dataRetrieval</code> package (you can learn more about <code>dataRetrieval</code> in <a rel="nofollow" href="https://owi.usgs.gov/R/training-curriculum/usgs-packages/" target="_blank">this curriculum</a>). Three USGS gage sites in Wisconsin were chosen because they have data for all three water quality parameters (flow, total suspended solids, and inorganic nitrogen) we are using in this example.</p>
<pre><code>library(dataRetrieval)
library(dplyr) # for `rename` &amp; `select`
library(tidyr) # for `gather`
library(ggplot2)

# Get the data by giving site numbers and parameter codes
# 00060 = stream flow, 00530 = total suspended solids, 00631 = concentration of inorganic nitrogen 
wi_daily_wq &lt;- readNWISdv(siteNumbers = c(&quot;05430175&quot;, &quot;05427880&quot;, &quot;05427927&quot;),
                          parameterCd = c(&quot;00060&quot;, &quot;00530&quot;, &quot;00631&quot;),
                          startDate = &quot;2017-08-01&quot;, endDate = &quot;2017-08-31&quot;)

# Clean up data to have human-readable names + move data into long format
wi_daily_wq &lt;- renameNWISColumns(wi_daily_wq, 
                                 p00530 = &quot;TSS&quot;,
                                 p00631 = &quot;InorganicN&quot;) %>% 
  select(-ends_with(&quot;_cd&quot;)) %>% 
  gather(key = &quot;parameter&quot;, value = &quot;value&quot;, -site_no, -Date)

# Setup plot without facets
p &lt;- ggplot(data = wi_daily_wq, aes(x = Date, y = value)) + 
  geom_point(aes(color = site_no)) + 
  theme_bw()

# Now, we can look at the plot and see how it looks before we facet
# Obviously, the scales are off because we are plotting flow with concentrations
p
</code></pre>
<p><img src="https://i0.wp.com/owi.usgs.gov/blog/static/beyond-basic-plotting/nofacetplot-1.png?w=456&ssl=1" alt="Basic ggplot2 timeseries with 3 parameters represented in one: inorganic N, TSS, and flow." title="ggplot2 setup before faceting" data-recalc-dims="1"></p>
<p>Now, we know that we can’t keep these different parameters on the same plot. We could have written code to filter the data frame to the appropriate values and make a plot for each of them, but we can also take advantage of <code>facet_grid</code>. Since the resulting three plots that we want will all share an x axis (Date), we can imagine slicing up the figure in the vertical direction so that the x axis remains in-tact but we end up with three different y axes. We can do this using <code>facet_grid</code> and a formula syntax, <code>y ~ x</code>. So, if you want to divide the figure along the y axis, you put variable in the data that you want to use to decide which plot data goes into as the first entry in the formula. You can use a <code>.</code> if you do not want to divide the plot in the other direction.</p>
<pre><code># Add vertical facets, aka divide the plot up vertically since they share an x axis
p + facet_grid(parameter ~ .)
</code></pre>
<p><img src="https://i2.wp.com/owi.usgs.gov/blog/static/beyond-basic-plotting/verticalfacetplot-1.png?w=456&ssl=1" alt="Basic ggplot2 timeseries with inorganic N, TSS, and flow represented in three different facets along the y axis." title="ggplot2 basic vertical facet" data-recalc-dims="1"></p>
<p>The result is a figure divided along the y axis based on the unique values of the <code>parameter</code> column in the data.frame. So, we have three plots in one figure. They still all share the same axes, which works for the x axis but not for the y axes. We can change that by letting the y axes scale freely to the data that appears just on that facet. Add the argument <code>scales</code> to <code>facet_grid</code> and specify that they should be “free” rather than the default “fixed”.</p>
<pre><code># Add vertical facets, but scale only the y axes freely
p + facet_grid(parameter ~ ., scales = &quot;free_y&quot;)
</code></pre>
<p><img src="https://i2.wp.com/owi.usgs.gov/blog/static/beyond-basic-plotting/verticalfacetplotfreescale-1.png?w=456&ssl=1" alt="Basic ggplot2 timeseries with inorganic N, TSS, and flow represented in three individually scaled facets along the y axis." title="ggplot2 with freely scaled, vertical facets" data-recalc-dims="1"></p>
<p>From here, there might be a few things you want to change about how it’s labelling the facets. We would probably want the y axis labels to say the parameter and units on the left side. So, we can adjust how the facets are labeled and styled to become our y axis labels.</p>
<pre><code>p + facet_grid(parameter ~ ., scales = &quot;free_y&quot;,
               switch = &quot;y&quot;, # flip the facet labels along the y axis from the right side to the left
               labeller = as_labeller( # redefine the text that shows up for the facets
                 c(Flow = &quot;Flow, cfs&quot;, InorganicN = &quot;Inorganic N, mg/L&quot;, TSS = &quot;TSS, mg/L&quot;))) +
  ylab(NULL) + # remove the word &quot;values&quot;
  theme(strip.background = element_blank(), # remove the background
        strip.placement = &quot;outside&quot;) # put labels to the left of the axis text
</code></pre>
<p><img src="https://i2.wp.com/owi.usgs.gov/blog/static/beyond-basic-plotting/verticalfacetplotfixedlabels-1.png?w=456&ssl=1" alt="Basic ggplot2 timeseries with inorganic N, TSS, and flow represented in three individually scaled facets along the y axis, and appropriately labeled axes." title="ggplot2 with facet labels as the y axis labels" data-recalc-dims="1"></p>
<p>There are still other things you can do with facets, such as using <code>space = &quot;free&quot;</code>. The <a rel="nofollow" href="http://www.cookbook-r.com/Graphs/Facets_(ggplot2)/" target="_blank">Cookbook for R facet examples</a> have even more to explore!</p>
<h2>Using <code>cowplot</code> to create multiple plots in one figure</h2>
<p>When you are creating multiple plots and they do not share axes or do not fit into the facet framework, you could use the packages <code>cowplot</code> or <code>patchwork</code> (very new!), or the <code>grid.arrange</code> function from <code>gridExtra</code>. In this blog post, we will show how to use <code>cowplot</code>, but you can explore the features of <code>patchwork</code> <a rel="nofollow" href="https://github.com/thomasp85/patchwork" target="_blank">here</a>.</p>
<p>The package called <code>cowplot</code> has nice wrapper functions for ggplot2 plots to have shared legends, put plots into a grid, annotate plots, and more. Below is some code that shows how to use some of these helpful <code>cowplot</code> functions to create a figure that has three plots and a shared title.</p>
<p>Just as in the previous example, we will download USGS water data from the USGS NWIS using the <code>dataRetrieval</code> package (find out more about <code>dataRetrieval</code> in <a rel="nofollow" href="https://owi.usgs.gov/R/training-curriculum/usgs-packages/" target="_blank">this curriculum</a>). This USGS gage site on the Yahara River in Wisconsin was chosen because it has data for all three water quality parameters (flow, total suspended solids, and inorganic nitrogen) we are using in this example.</p>
<pre><code>library(dataRetrieval)
library(dplyr) # for `rename`
library(tidyr) # for `gather`
library(ggplot2)
library(cowplot)

# Get the data
yahara_daily_wq &lt;- readNWISdv(siteNumbers = &quot;05430175&quot;, 
                          parameterCd = c(&quot;00060&quot;, &quot;00530&quot;, &quot;00631&quot;),
                          startDate = &quot;2017-08-01&quot;, endDate = &quot;2017-08-31&quot;)

# Clean up data to have human-readable names
yahara_daily_wq &lt;- renameNWISColumns(yahara_daily_wq, 
                                     p00530 = &quot;TSS&quot;,
                                     p00631 = &quot;InorganicN&quot;)

# Create the three different plots
flow_timeseries &lt;- ggplot(yahara_daily_wq, aes(x=Date, y=Flow)) + 
  geom_point() + theme_bw()

yahara_daily_wq_long &lt;- gather(yahara_daily_wq, Nutrient, Nutrient_va, TSS, InorganicN)
nutrient_boxplot &lt;- ggplot(yahara_daily_wq_long, aes(x=Nutrient, y=Nutrient_va)) +
  geom_boxplot() + theme_bw()

tss_flow_plot &lt;- ggplot(yahara_daily_wq, aes(x=Flow, y=TSS)) + 
  geom_point() + theme_bw()

# Create Flow timeseries plot that spans the grid by making one plot_grid
#   and then nest it inside of a second. Also, include a title at the top 
#   for the whole figure. 
title &lt;- ggdraw() + draw_label(&quot;Conditions for site 05430175&quot;, fontface='bold')
bottom_row &lt;- plot_grid(nutrient_boxplot, tss_flow_plot, ncol = 2, labels = &quot;AUTO&quot;)
plot_grid(title, bottom_row, flow_timeseries, nrow = 3, labels = c(&quot;&quot;, &quot;&quot;, &quot;C&quot;),
          rel_heights = c(0.2, 1, 1))
</code></pre>
<p><img src="https://i1.wp.com/owi.usgs.gov/blog/static/beyond-basic-plotting/cowplotmulti-1.png?w=456&ssl=1" alt="Three plots in one figure: boxplot of inorganic N &amp; TSS, TSS vs flow, and hydrograph." title="Multi-plot figure generated using cowplot." data-recalc-dims="1"></p>
	<p>
<div>
<div>To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://owi.usgs.gov/blog/beyond-basic-plotting/"> The USGS OWI blog </a></strong>.</div>
<hr>
<a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers.com</a> offers <strong><a rel="nofollow" href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers">daily e-mail updates</a></strong> about <a rel="nofollow" href="https://www.r-project.org/" title="The R Project for Statistical Computing">R</a> news and <a rel="nofollow" href="https://www.r-bloggers.com/search/tutorial" title="R tutorials">tutorials</a> on topics such as: <a rel="nofollow" href="https://www.r-bloggers.com/search/data%20science" title="Data science">Data science</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/Big%20Data" title="Big Data">Big Data, <a rel="nofollow" href="https://www.r-users.com/" title="R jobs">R jobs</a>, visualization (<a rel="nofollow" href="https://www.r-bloggers.com/search/ggplot2" title="ggplot and ggplot2 tutorials">ggplot2</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/boxplot" title="Boxplots using lattice and ggplot2 tutorials">Boxplots</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/map" title="Maps and gis">maps</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/animation" title="Animation in R">animation</a>), programming (<a rel="nofollow" href="https://www.r-bloggers.com/search/RStudio" title="RStudio IDE for R">RStudio</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/sweave" title="Sweave and literate programming">Sweave</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/LaTeX" title="LaTeX in R">LaTeX</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/SQL" title="SQL and databases">SQL</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/eclipse" title="Eclipse IDE for R">Eclipse</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/git" title="git and github, Version Control System">git</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/hadoop" title="Large data in R using Hadoop">hadoop</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/Web+Scraping" title="Web Scraping of google, facebook, yahoo, twitter and more using R">Web Scraping</a>) statistics (<a rel="nofollow" href="https://www.r-bloggers.com/search/regression" title="Regressions and ANOVA analysis tutorials">regression</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/PCA" title="principal component analysis tutorial">PCA</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/time+series" title="Time series">time series</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/trading" title="finance trading">trading</a>) and more...
<img width="1" alt="" src="http://feeds.feedburner.com/~r/RBloggers/~4/5f0-GTEbJR4" height="1"></a></div>