gridExtra Introduction

This code through dives into the ggplot2 package and how we can utilize the gridExtra package to arrange and combine plots for easy comparison. For this code through, we will be using the “mtcars” data set inside R that analyzes various makes of cars and their stats such as weight, mpg, cylinders, hp, and various others.

Overview

The main goal is to show other ways we might utilize combining plots for easier analysis. We will begin by creating some simple examples that show how you can analyze different types of data.

We will then create move onto an example from class that shows how we might use gridExtra similarly to how we used tmap for clustering and combining the plots as well.

Why gridExtra is Valuable

As we are learning more and more about data analysis, it is important to have more tools at our disposal for data visualization. While we have seen various ways to create plots to show results, it is important to be able to show various graphs associated with our data to better understand the importance. Furthermore, gridExtra works with other grid-based graphics and plotting libraries in R, which makes it versatile when combining multiple plots from various packages.

Basic Example

We begin by installing and loading the necessary packages as well as loading our data set mtcars. If you wish, you can create a new data set using “data = head(mtcars, )” and input a number following the comma to see how this might look with less data, but since we only have 32 observations in the data set, this is not necessary.

After we import our data, we then create two plots using ggplot() and call our data. You can then assign specific variables to plot on the x and y axis. I chose to use cylinders (“cyl”) and miles per galon (“mpg”) as my x and y axis for the first plot and miles-per-galon (“mpg”) and weight (“wt”) as my x and y values for the second plot.

After creating our two plots, we can then call grid.arrange() to plot the two scatterplots side-by-side. It is important to note that “ncol =” will indicate how many grids you wish to have side-by-side. For example, “ncol = 2” will show two grids together but “ncol = 1” will place the grids on top of each other. A better way to think of it is how many columns you wish to see, but instead of columns of data you are looking at grids of visualized data.

# Install and load necessary packages
library(gridExtra)
## Warning: package 'gridExtra' was built under R version 4.3.2
library(ggplot2)
library(ggthemes)

# Import some data
cars_data <- mtcars 

# Create two ggplot2 plots
plot1 <- ggplot(cars_data, aes(x = cyl, y = mpg)) +
  geom_point() +
  ggtitle("Plot 1") + 
  scale_x_continuous(breaks = (c(4, 6, 8)))

plot2 <- ggplot(cars_data, aes(x = mpg, y = wt)) +
  geom_point() +
  ggtitle("Plot 2")

# Arrange the plots using gridExtra
grid.arrange(plot1, plot2, ncol = 2)

## Advanced Example No. 1

For the first example, we call the cars_data data set we created in the basic example and create 3 new plots using the same setup. This time, we will add themes to each map to make grids not so bland. In the geom_point() function under ggplot2, simply use “color =” to make your sets a different color and add the theme_ function to change the look of the grids.

In order to properly arrange more than two grids, we need to call the arrangeGrob function in our grid.arrange code. This allows us to call multiple “grobs” or grid graphical objects to the plot. In this way, we can place two grids together and have one underneath allowing for more visualization of our data.

# Install and load necessary packages
library(gridExtra)
library(ggplot2)

# Call the cars_data data set
set.seed(12345)

# Create three ggplot2 plots
plot1 <- ggplot(cars_data, aes(x = hp, y = mpg)) +
  geom_point(color = "lightblue") +
  ggtitle("Plot 1") +
  theme_dark()

plot2 <- ggplot(cars_data, aes(x = cyl, y = hp)) +
  geom_point(color = "red") +
  ggtitle("Plot 2") +
  theme_minimal()

plot3 <- ggplot(cars_data, aes(x = wt, y = hp)) +
  geom_point(color = "maroon") +
  ggtitle("Plot 3") +
  theme_classic()

# Arrange the plots using gridExtra with custom layout
grid.arrange(
  arrangeGrob(plot1, plot2, ncol = 2),  # Top row with two plots
  plot3,                                # Bottom row with one plot
  heights = c(2, 3)                     # Set relative heights of rows
)

Advanced Example No. 2

To better understand how we can utilize gridExtra, I decided to use an example from our previous homework for Lab 04 where we utilized tmap to create our dorling cartograms and instead use gridExtra to see how these two may differ in some regards.

Unfortunately, there are still some kinks to the gridExtra package that I am working out and as such as I was unable to exactly duplicate our Dorling Cartograms from the previous lab but I was able to get it to a working point to better show how one might arrange and compare plots.

# Load required libraries
library(tidyverse)
## Warning: package 'tibble' was built under R version 4.3.2
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.3     ✔ readr     2.1.4
## ✔ forcats   1.0.0     ✔ stringr   1.5.0
## ✔ lubridate 1.9.3     ✔ tibble    3.2.1
## ✔ purrr     1.0.2     ✔ tidyr     1.3.0
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::combine() masks gridExtra::combine()
## ✖ dplyr::filter()  masks stats::filter()
## ✖ dplyr::lag()     masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(tidycensus)
library(sf)
## Linking to GEOS 3.11.2, GDAL 3.6.2, PROJ 9.2.0; sf_use_s2() is TRUE
library(censusapi)
## 
## Attaching package: 'censusapi'
## 
## The following object is masked from 'package:methods':
## 
##     getFunction
library(cartogram)
## Warning: package 'cartogram' was built under R version 4.3.2
library(gridExtra)

s.type <- "HTML"

# Set the census API key
census_api_key("2e56e113b64a07599410e905db69dbcc44a77885")
## To install your API key for use in future sessions, run this function with `install = TRUE`.
# Load the crosswalk data
crosswalk <- read.csv(
  "https://raw.githubusercontent.com/DS4PS/cpp-529-master/master/data/cbsatocountycrosswalk.csv",
  stringsAsFactors = FALSE,
  colClasses = "character"
)

# Filter San Diego data
these.msp <- crosswalk$msaname == grep("^SAN DIEGO", crosswalk$msaname, value = TRUE)
these.fips <- crosswalk$fipscounty[these.msp]
these.fips <- na.omit(these.fips)

# Extract state and county FIPS codes
state.fips <- substr(these.fips, 1, 2)
county.fips <- substr(these.fips, 3, 5)

# Create a data frame with FIPS information
fips_df <- cbind(these.fips, state.fips, county.fips)

# Get San Diego population data
sd.pop <- get_acs(
  geography = "tract",
  variables = "B01003_001",
  state = state.fips,
  county = county.fips,
  geometry = TRUE
) %>%
  select(GEOID, estimate) %>%
  rename(POP = estimate)
## Getting data from the 2017-2021 5-year ACS
## Downloading feature geometry from the Census website.  To cache shapefiles for use in future sessions, set `options(tigris_use_cache = TRUE)`.
## 
  |                                                                            
  |                                                                      |   0%
  |                                                                            
  |=                                                                     |   1%
  |                                                                            
  |=                                                                     |   2%
  |                                                                            
  |==                                                                    |   2%
  |                                                                            
  |==                                                                    |   3%
  |                                                                            
  |===                                                                   |   4%
  |                                                                            
  |===                                                                   |   5%
  |                                                                            
  |====                                                                  |   5%
  |                                                                            
  |====                                                                  |   6%
  |                                                                            
  |=====                                                                 |   7%
  |                                                                            
  |======                                                                |   8%
  |                                                                            
  |======                                                                |   9%
  |                                                                            
  |=======                                                               |   9%
  |                                                                            
  |=======                                                               |  10%
  |                                                                            
  |========                                                              |  11%
  |                                                                            
  |========                                                              |  12%
  |                                                                            
  |=========                                                             |  12%
  |                                                                            
  |=========                                                             |  13%
  |                                                                            
  |=========                                                             |  14%
  |                                                                            
  |==========                                                            |  14%
  |                                                                            
  |==========                                                            |  15%
  |                                                                            
  |===========                                                           |  15%
  |                                                                            
  |===========                                                           |  16%
  |                                                                            
  |============                                                          |  17%
  |                                                                            
  |============                                                          |  18%
  |                                                                            
  |=============                                                         |  18%
  |                                                                            
  |=============                                                         |  19%
  |                                                                            
  |==============                                                        |  19%
  |                                                                            
  |==============                                                        |  20%
  |                                                                            
  |===============                                                       |  21%
  |                                                                            
  |===============                                                       |  22%
  |                                                                            
  |================                                                      |  22%
  |                                                                            
  |================                                                      |  23%
  |                                                                            
  |=================                                                     |  24%
  |                                                                            
  |=================                                                     |  25%
  |                                                                            
  |==================                                                    |  26%
  |                                                                            
  |===================                                                   |  27%
  |                                                                            
  |===================                                                   |  28%
  |                                                                            
  |====================                                                  |  28%
  |                                                                            
  |====================                                                  |  29%
  |                                                                            
  |=====================                                                 |  29%
  |                                                                            
  |=====================                                                 |  30%
  |                                                                            
  |======================                                                |  31%
  |                                                                            
  |======================                                                |  32%
  |                                                                            
  |=======================                                               |  33%
  |                                                                            
  |========================                                              |  34%
  |                                                                            
  |========================                                              |  35%
  |                                                                            
  |=========================                                             |  35%
  |                                                                            
  |=========================                                             |  36%
  |                                                                            
  |==========================                                            |  36%
  |                                                                            
  |==========================                                            |  37%
  |                                                                            
  |==========================                                            |  38%
  |                                                                            
  |===========================                                           |  38%
  |                                                                            
  |===========================                                           |  39%
  |                                                                            
  |============================                                          |  40%
  |                                                                            
  |============================                                          |  41%
  |                                                                            
  |=============================                                         |  42%
  |                                                                            
  |==============================                                        |  43%
  |                                                                            
  |===============================                                       |  44%
  |                                                                            
  |===============================                                       |  45%
  |                                                                            
  |================================                                      |  45%
  |                                                                            
  |================================                                      |  46%
  |                                                                            
  |=================================                                     |  46%
  |                                                                            
  |=================================                                     |  47%
  |                                                                            
  |=================================                                     |  48%
  |                                                                            
  |==================================                                    |  48%
  |                                                                            
  |==================================                                    |  49%
  |                                                                            
  |===================================                                   |  50%
  |                                                                            
  |===================================                                   |  51%
  |                                                                            
  |====================================                                  |  52%
  |                                                                            
  |=====================================                                 |  53%
  |                                                                            
  |======================================                                |  54%
  |                                                                            
  |======================================                                |  55%
  |                                                                            
  |=======================================                               |  56%
  |                                                                            
  |========================================                              |  56%
  |                                                                            
  |========================================                              |  57%
  |                                                                            
  |=========================================                             |  58%
  |                                                                            
  |=========================================                             |  59%
  |                                                                            
  |==========================================                            |  59%
  |                                                                            
  |==========================================                            |  60%
  |                                                                            
  |==========================================                            |  61%
  |                                                                            
  |===========================================                           |  61%
  |                                                                            
  |===========================================                           |  62%
  |                                                                            
  |============================================                          |  63%
  |                                                                            
  |=============================================                         |  64%
  |                                                                            
  |=============================================                         |  65%
  |                                                                            
  |==============================================                        |  66%
  |                                                                            
  |===============================================                       |  67%
  |                                                                            
  |===============================================                       |  68%
  |                                                                            
  |================================================                      |  68%
  |                                                                            
  |================================================                      |  69%
  |                                                                            
  |=================================================                     |  70%
  |                                                                            
  |==================================================                    |  71%
  |                                                                            
  |==================================================                    |  72%
  |                                                                            
  |===================================================                   |  72%
  |                                                                            
  |====================================================                  |  74%
  |                                                                            
  |=====================================================                 |  75%
  |                                                                            
  |=====================================================                 |  76%
  |                                                                            
  |======================================================                |  77%
  |                                                                            
  |======================================================                |  78%
  |                                                                            
  |=======================================================               |  78%
  |                                                                            
  |========================================================              |  80%
  |                                                                            
  |========================================================              |  81%
  |                                                                            
  |=========================================================             |  81%
  |                                                                            
  |==========================================================            |  83%
  |                                                                            
  |===========================================================           |  84%
  |                                                                            
  |============================================================          |  85%
  |                                                                            
  |============================================================          |  86%
  |                                                                            
  |=============================================================         |  88%
  |                                                                            
  |==============================================================        |  88%
  |                                                                            
  |==============================================================        |  89%
  |                                                                            
  |===============================================================       |  90%
  |                                                                            
  |================================================================      |  91%
  |                                                                            
  |=================================================================     |  93%
  |                                                                            
  |==================================================================    |  94%
  |                                                                            
  |===================================================================   |  95%
  |                                                                            
  |===================================================================   |  96%
  |                                                                            
  |====================================================================  |  97%
  |                                                                            
  |===================================================================== |  98%
  |                                                                            
  |===================================================================== |  99%
  |                                                                            
  |======================================================================| 100%
# Recode the GEOID variable
sd.pop$GEOID <- sub(".", "", sd.pop$GEOID)

# Load census data
URL <- "https://github.com/DS4PS/cpp-529-master/raw/master/data/ltdb_std_2010_sample.rds"
census.dat <- readRDS(gzcon(url(URL)))

# Merge population data with census data
sdd <- merge(sd.pop, census.dat, by.x = "GEOID", by.y = "tractid")

# Remove empty polygons
sdd <- sdd[!st_is_empty(sdd), ]

# Project map and remove empty tracts
sdd.sp <- st_transform(sdd, crs = st_crs("+proj=utm +zone=33 +datum=WGS84"))
sdd.sp <- sdd.sp[sdd.sp$POP != 0 & (!is.na(sdd.sp$POP)), ]

# Convert census tract polygons to dorling cartogram
sdd.sp$pop.w <- sdd.sp$POP / 4000
sd_dorling <- cartogram_dorling(x = sdd.sp, weight = "pop.w", k = 0.05)


# Simple example
p1 <- ggplot() + 
  geom_sf(data = sdd.sp, aes(fill = pop.w)) + 
  ggtitle("Original Map")
p1

# Advanced example with the dorling cartogram
p2 <- ggplot(col = "hinc12", n = 7) + 
  geom_sf(data = sd_dorling, aes(fill = sd_dorling$pop.w)) + 
  ggtitle("Dorling Cartogram \nof Household Income \n for San Diego")
p2

# Arrange plots using gridExtra
grid.arrange(p1, p2, ncol = 2, top = "San Diego Population Visualization")

Conclusion

In conclusion, there are a variety of different uses for the gridExtra package and I am still learning with a bunch of different nuances. To start, I do not believe this package is as effective as other packages we have used in our class such as tmap. Tmap made it more fluid when combining various tmaps whereas gridExtra feels like there are a number of different steps involved in creating, applying themes, and overall layouts of the grids. However, I still believe it has its uses for data visualization. For anything involving numbers or statistical graphs, this is an invaluable package to know and use by making it easier to box together useful information in data visualization.

Works Cited

Nicholas Dove - https://sabahzero.github.io/dataviz/journal_fig_tutorial

R Peng, D. (2019). “Exploring the grid package”. CRC Press. Retrieved from https://bookdown.org/rdpeng/RProgDA/the-grid-package.html

Baptiste Auguié. (2019). “Laying out multiple plots on a page”. Retrieved from https://cran.r-project.org/web/packages/egg/vignettes/Ecosystem.html

Note that the echo = FALSE parameter was added to the code chunk to prevent printing of the R code that generated the plot.