A Comprehensive Guide to Data Visualization with ggplot2 in R

Data visualization is a crucial skill for any data scientist or analyst. Being able to create informative and aesthetically pleasing graphs allows you to effectively explore datasets and communicate insights to others. When it comes to making professional-quality plots in R, ggplot2 is the go-to package for many.

In this guide, we‘ll take a deep dive into ggplot2 and learn how to create a wide variety of charts and customize them to your heart‘s content. We‘ll cover everything you need to know to start making publication-worthy plots in R. Let‘s get started!

What is ggplot2?

ggplot2 is a powerful and flexible data visualization package for the R programming language. It was created by Hadley Wickham and is now maintained by the RStudio team.

The "gg" in ggplot2 stands for "grammar of graphics." This refers to the theoretical framework the package is built on top of, which breaks up a statistical graphic into semantic components like data, geometric objects (points, lines, bars, etc.), scales, and facets. By mapping data attributes to visual properties, ggplot2 allows you to build up plots layer-by-layer.

Compared to base R plotting functions, ggplot2 provides a more programmatic interface for specifying plots. This lends itself well to reusable templates and functions. The learning curve may be slightly steeper than with base R, but ggplot2 is well worth the effort to master.

Installing and loading ggplot2

Before we can start plotting, we need to install ggplot2 (if you haven‘t already) and load it into our R session.

To install the package from CRAN:

install.packages("ggplot2")

Then, to load ggplot2:

library(ggplot2) 

We‘re now ready to make some plots!

The basics of a ggplot

A ggplot figure is made up of a number of key components:

  • Data: The dataset to be plotted, typically a data frame
  • Aesthetics (aes): Visual properties of the elements in the plot, like the x/y position, color, size, shape, etc. These are mapped to variables in the data.
  • Geometries (geom_): The geometric objects used to represent the data, such as points, lines, bars, etc. You can think of these as the "layers" of the plot.
  • Scales: Maps between the data units and visual properties (position, color, size, etc.)
  • Facets: Splits the data into subplots based on the values of one or more discrete variables
  • Theme: Controls the appearance of non-data elements like the plot background, gridlines, axis labels, legends, etc.

Here‘s a simple example that illustrates the basic usage of ggplot2:

ggplot(data = mpg) +
  aes(x = displ, y = hwy) +
  geom_point()

This code creates a scatterplot using the built-in mpg dataset, with engine displacement on the x-axis and highway miles per gallon on the y-axis. We start with the ggplot() function, specifying the dataset. Then we map variables to visual properties inside the aes() function. Finally, we say what geometric objects to draw using a geom_ function, in this case points.

Common plot types

Now let‘s recreate some common chart types using ggplot2. While there are many geoms and extensions available, these examples will cover most everyday plotting needs.

Scatterplot

As we saw above, making a scatterplot requires mapping variables to the x and y aesthetics, then using the geom_point() function:

ggplot(data = iris) + 
  aes(x = Sepal.Length, y = Sepal.Width) +
  geom_point()

You can map a third variable to the color or size of points to encode more information:

ggplot(data = iris) +
  aes(x = Sepal.Length, y = Sepal.Width, color = Species, size = Petal.Length) +
  geom_point()

Line chart

Line charts are created similarly to scatterplots, except we use the geom_line() function instead:

ggplot(data = economics) +
  aes(x = date, y = unemploy/pop) + 
  geom_line()

Bar chart

The geom_bar() function makes bar charts based on counts of a categorical variable, while geom_col() is used for plotting pre-summarized data.

# Bar chart of counts
ggplot(data = diamonds) +
  aes(x = cut) +
  geom_bar()

# Bar chart of totals
ggplot(data = mpg) +
  aes(x = manufacturer, y = sum(cty)) + 
  geom_col()

Histogram

Visualize the distribution of a continuous variable with geom_histogram():

ggplot(data = faithful) +
  aes(x = waiting) + 
  geom_histogram(binwidth = 5)

Box plot

Box plots are great for comparing the distributions of a continuous variable across levels of a categorical variable. Use geom_boxplot():

ggplot(data = ToothGrowth) +
  aes(x = supp, y = len) +
  geom_boxplot()

Customizing plots

One of ggplot2‘s biggest strengths is the ability to customize and polish plots for presentation. Here are a few key ways you can tweak the appearance of your figures.

Modifying scales

To change the appearance of axes and legends, use scale_ functions:

ggplot(data = mpg) +
  aes(x = displ, y = hwy, color = drv) +
  geom_point() + 
  scale_x_continuous(breaks = seq(0,8,1)) +
  scale_y_continuous(limits = c(0, 50)) + 
  scale_color_brewer(palette = "Set1")

Adjusting themes

The theme() function allows you to modify the non-data elements of a plot:

ggplot(data = economics) + 
  aes(x = date, y = unemploy/pop) +
  geom_line() + 
  theme_minimal() +
  theme(
    axis.title = element_text(size = 16),
    panel.grid.minor = element_blank()  
  )

Adding annotations

Text, lines, and other annotations can be added with functions like labs(), annotate(), and geom_text():

ggplot(data = mpg) +
  aes(x = displ, y = hwy, label = model) + 
  geom_point() +
  geom_text(check_overlap = TRUE, vjust = "bottom", hjust = "right") +
  labs(
    title = "Fuel efficiency by engine size",
    x = "Engine displacement (L)", 
    y = "Highway miles per gallon"
  )

Faceting

To show small multiples of a plot based on levels of categorical variables, use facet_wrap() or facet_grid():

ggplot(data = iris) +
  aes(x = Sepal.Length, y = Sepal.Width, color = Species) +
  geom_point() + 
  facet_wrap(~ Species)

Saving plots

Use ggsave() to export plots from R:

ggsave("my_plot.png", width = 6, height = 4)

This will save the last plot created to a 6×4 inch PNG file.

Putting it all together

To cement these concepts, let‘s walk through a complete exploratory analysis of a real-world dataset. We‘ll use data on passenger flights from the Bureau of Transportation Statistics.

First, load the data into R:

flights <- read.csv("flights.csv")

Let‘s start by looking at the distribution of flight delays:

ggplot(flights) + 
  aes(x = dep_delay) +
  geom_histogram(binwidth = 15) + 
  scale_x_continuous(limits = c(-50, 300))

There‘s a long tail of very delayed flights. Let‘s zoom in on delays of 3 hours or less:

ggplot(flights) + 
  aes(x = dep_delay) +
  geom_histogram(binwidth = 5) + 
  scale_x_continuous(limits = c(-15, 180))

Do some months have worse delays than others?

ggplot(flights) +
  aes(x = factor(month), y = dep_delay) +
  geom_boxplot() +
  scale_y_continuous(limits = c(-10, 100)) + 
  labs(x = "Month", y = "Departure delay (minutes)")

It looks like summer months tend to have longer delays than winter. Holidays like Thanksgiving and Christmas probably have an impact too. Speaking of which, do some days of the week have more delays?

ggplot(flights) +
  aes(x = factor(day_of_week), y = dep_delay) +
  geom_boxplot() +
  scale_y_continuous(limits = c(-10, 75)) +
  labs(x = "Day of week (1 = Monday)", y = "Departure delay (minutes)")

Weekends actually look better than weekdays. That makes sense, since there‘s usually less business travel on weekends.

Finally, let‘s see if some airlines have better or worse on-time performance than others:

airline_summary <- flights %>%
  group_by(carrier) %>%
  summarize(
    median_delay = median(dep_delay, na.rm = TRUE),
    n_flights = n()
  ) %>%
  filter(n_flights > 1000)

ggplot(airline_summary) +
  aes(x = carrier, y = median_delay) + 
  geom_col() +
  scale_y_continuous(expand = c(0,0), limits = c(0, 20)) +
  labs(x = "Airline", y = "Median departure delay (minutes)") +
  coord_flip()

There are clear differences between airlines. Hawaiian and Alaska look to have the best track record, while regional carriers like Envoy Air struggle to depart on time.

Hopefully this analysis gives you a sense of how you can use ggplot2 to quickly explore a dataset and communicate insights visually. The more you practice with it, the more natural the grammar of graphics framework will become!

Learning more

We‘ve really only scratched the surface of what ggplot2 can do. Here are some resources to continue building your skills:

With ggplot2 in your toolkit, you‘ll be able explore and present data in a concise and compelling way. As Hadley Wickham says in his book:

"Visualization is an incredibly powerful tool for insight generation, but to gain that insight, you must first learn the language. ggplot2 is one dialect of the language of graphics. Once you‘re fluent, you‘ll find visualization an invaluable tool for communicating with others, and for exploring your data and generating new ideas."

Happy plotting!

How useful was this post?

Click on a star to rate it!

Average rating 0 / 5. Vote count: 0

No votes so far! Be the first to rate this post.

Similar Posts