Visualization with ggplot in R

Visualization is a key part of statistical analyses, especially in systems engineering! Visuals themselves are often the analysis themselves! In this tutorial, we're going to learn how to visualize data in the ggplot2 package.

Please follow along using the code below!

Getting Started

Loading Packages

Let's load our packages with library().

# Data viz and data manipulation packages
library(ggplot2)
library(dplyr)
# Data sources
library(gapminder)

Notes:

  1. SAVE YOUR SCRIPT.
  2. Always comment your code (what I'm doing now),
  3. use lots of spaces, and keep it clean.

Gapminder data

Economist Hans Rosling made a dataset that examines change in life expectancy over time for most countries in the world. It is contained in the gapminder package!

# Let's view it. (see console below)
gapminder

Each row is a country-year, marking the life expectancy, population, and gross domestic product (GDP) per capita. On your end, you can only can see some of it, right?

Let's check out what vectors are in this dataframe, using the glimpse function from the dplyr package.

# (Remember, a vector is a column in a spreadsheet;
# a data.frame is a spreadsheet.)
glimpse(gapminder)
# Nice, we can see things more concisely.

Our data has six variables. Great!

Your first scatterplot

Using the gapminder data, let's map a series of vectors to become aesthetic features in the visualization (point, colors, fills, etc.).

ggplot(data = gapminder, mapping = aes(
  # Let's make the x-axis gross-domestic product per capita (wealth per person)
  x = gdpPercap,
  # Let's make the y-axis country life expectancy
  y = lifeExp))
Empty ggplot canvas mapping gdpPercap to the x-axis and lifeExp to the y-axis, with no geom layer added yet

Huh! We made an empty graph. Cool.

That's because ggplot needs helper functions to add aesthetic features to the graph.

For example, adding + geom_point() will overlay a scatterplot.

# Make a scatterplot
ggplot(data = gapminder, mapping = aes(x = gdpPercap, y = lifeExp)) + # same as above, except "+"
  geom_point()
Scatterplot of GDP per capita versus life expectancy for all gapminder country-years
LC 01
Wealth and life expectancy

What kind of relationship does this graph show? Why might it matter to policymakers?

LC 02
Adjusting point transparency

What happens when you add the alpha, changing its values in the 3 visuals below?

# Run the following code:

ggplot(data = gapminder, mapping = aes(x = gdpPercap, y = lifeExp)) +
  geom_point(alpha = 0.2)

ggplot(data = gapminder, mapping = aes(x = gdpPercap, y = lifeExp)) +
  geom_point(alpha = 0.5)

ggplot(data = gapminder, mapping = aes(x = gdpPercap, y = lifeExp)) +
                               geom_point(alpha = 1)
Scatterplot of GDP per capita vs. life expectancy with geom_point alpha = 0.2 (mostly transparent points) Scatterplot of GDP per capita vs. life expectancy with geom_point alpha = 0.5 Scatterplot of GDP per capita vs. life expectancy with geom_point alpha = 1 (fully opaque points)
LC 03
Single color vs. mapped color

We can make it more visually appealing. What happens when we do each of the following?

  1. If you want to make it a single color, where do you need to write color = ...?
  2. If you want to make it multiple colors according to a vector, where do you need to write color = ?
# Run the following code:

# Version 1
ggplot(data = gapminder, mapping = aes(x = gdpPercap, y = lifeExp)) +
  geom_point(alpha = 0.5, color = "steelblue")

# Version 2
ggplot(data = gapminder, mapping = aes(x = gdpPercap, y = lifeExp, color = continent)) +
  geom_point(alpha = 0.5)

Improving our Visualizations

We can (and should!) make our visualizations much more readable by adding appropriate labels.

ggplot(data = gapminder, mapping = aes(x = gdpPercap, y = lifeExp,
color = continent)) +
  geom_point(alpha = 0.5) +
  # Add labels!
  labs(x = "GDP per capita (USD)", # label for x-values
    y = "Life Expectancy (years)", # label for y-values
    color = "Continent", # label for colors
    title = "Does Wealth affect Health?", # overall title
    subtitle = "Global Health Trends by Continent", # subtitle!
    caption = "Points display individual country-year observations.") # caption
Scatterplot of GDP per capita vs. life expectancy colored by continent, with title, subtitle, axis labels, and caption added via labs()

We can actually save visualizations as objects too, which can make things faster.

Let's save our visual as myviz

myviz = ggplot(data = gapminder, mapping = aes(x = gdpPercap, y = lifeExp,
                                                color = continent)) +
  geom_point(alpha = 0.5) +
  labs(x = "GDP per capita (USD)",
       y = "Life Expectancy (years)",
       color = "Continent",
       title = "Does Wealth affect Health?", # overall title
       subtitle = "Global Health Trends by Continent", # subtitle!
       caption = "Points display individual country-year observations.") # caption

Next, let's try a few more learning check that will ask you to try our ways to improve the quality and readability of your visuals!

LC 04
Recalling a saved plot

Now run myviz - what happens?

myviz
The saved myviz scatterplot, re-displayed by calling the myviz object
LC 05
Trying out themes

We can do better, adding things onto our myviz object! Try changing themes. What happens below?

# Version theme_bw
myviz +
# How about this theme?
theme_bw()
myviz displayed with theme_bw() applied
# Version theme_dark
myviz +
# How about this theme?
theme_dark()
myviz displayed with theme_dark() applied
# Version theme_classic
myviz +
# How about this theme?
theme_classic()
myviz displayed with theme_classic() applied

Visualizing diamonds data

Next, let's use the diamonds dataset, which comes with the ggplot2 package This is a dataset of over 50,000 diamond sales.

# Check out first 3 rows...
diamonds %>% head(3)

We can use this visualization to check whether the cut of diamonds really has any relationship with price.

glimpse(diamonds)

Looks like cut is an ordinal variable (fair, good, ideal, etc.), while price is numeric (eg. dollars). A boxplot might be helpful!

ggplot(data = diamonds, mapping = aes(x = cut, y = price, group = cut)) +
  # notice how we added group = cut, to tell it to use 5 different boxes, one per cut?
  geom_boxplot()
Boxplot of diamond price by cut, one box per cut category

Huh. How odd. Looks like the cut of diamonds has very little impact on what price they are sold at! At least at first glance — this marginal view hides the fact that better-cut diamonds tend to be smaller diamonds, and once you control for carat the picture reverses, a trap we'll learn to catch later in the course.

We can see lots of outliers at the top - really expensive diamonds for that cut.

LC 06
Fill by a single color vs. by group

Let's make this visualization more visually appealing.

What changed in the code to make these two different visual effects? Why? (Hint: fill.)

ggplot(data = diamonds, mapping = aes(x = cut, y = price, group = cut)) +
  geom_boxplot(fill = "steelblue")

ggplot(data = diamonds, mapping = aes(x = cut, y = price, group = cut, fill = cut)) +
  geom_boxplot()
Boxplot of diamond price by cut with all boxes filled the same steelblue color Boxplot of diamond price by cut with each box filled a different color based on cut

Visualizing Distributions

Different geom_ functions use colors in different ways, but this is a good example.

For example, below is a histogram. It visualizes the approximate distribution of a set of values.

We can see how frequently diamonds are sold for certain prices versus others.

ggplot(data = diamonds, mapping = aes(x = price, group = cut, fill = cut)) +
  geom_histogram(color = "white") + # notice new function here
  labs(x = "Price (USD)",
    y = "Frequency of Price (Count)",
    title = "US Diamond Sales")
Histogram of diamond price, stacked and filled by cut, showing a right-skewed distribution
LC 09
Shape of the diamond price distribution

Are most diamonds cheap or expensive? What type of distribution would you call this?

A Normal?
B Uniform?
C Left Skewed?
D Right Skewed?

Conclusion

You made it! You have now tried out a series of visuals in ggplot. We will use ggplot a lot in this course, so please be sure to reach out when you have questions, talk with others in your group, and work together to build great visualization skills! (Plus, it's super applicable professionally!)