No history yet

Advanced ggplot2 Techniques

Beyond the Basics

You've mastered the fundamentals of ggplot2: mapping variables to aesthetics and adding layers of geoms. Now it's time to elevate your plots from simple charts to compelling, publication-quality visualizations. We'll explore three powerful techniques: faceting, annotating, and theming.

Comparing with Facets

What if you want to see the relationship between engine displacement (displ) and highway miles per gallon (hwy), but broken down for each car class? You could create separate plots, but that's tedious. A better way is faceting, which creates a grid of subplots based on the values of a categorical variable.

Faceting is your tool for creating small multiples, a powerful technique for comparing different slices of your data side-by-side.

The most common function for this is facet_wrap(). You provide it a formula, like ~ class, to specify which variable to split the data by. ggplot2 then handles the rest, creating a separate panel for each category.

library(ggplot2)

# Base plot of displacement vs. highway MPG
# from the built-in 'mpg' dataset.
ggplot(mpg, aes(x = displ, y = hwy)) + 
  geom_point() + 
  # Create a separate plot for each car 'class'
  facet_wrap(~ class)

For faceting across two variables, you can use facet_grid(). Its formula takes the form rows ~ cols. For instance, you could examine how the number of cylinders (cyl) and the type of drive train (drv) interact.

ggplot(mpg, aes(x = displ, y = hwy)) + 
  geom_point() + 
  # Arrange plots in a grid: drive train by cylinders
  facet_grid(drv ~ cyl)

Notice how the default behavior is to keep the axes consistent across all panels. This is crucial for accurate comparison. However, if the scales of your facets differ dramatically, you can let them vary by setting scales = "free", "free_x", or "free_y".

Adding Context with Annotations

A good plot shows the data. A great plot tells a story. Annotations are the narrative elements you add to guide your audience's attention and highlight key insights. This can be as simple as labeling an important point or as complex as shading a region of interest.

To label specific points, you can use geom_text() or geom_label() on a filtered subset of your data. This links the label directly to a data point.

library(dplyr)

# Create a subset of data for labeling
# Let's highlight cars with hwy > 40
highlight_cars <- mpg %>% filter(hwy > 40)

ggplot(mpg, aes(x = displ, y = hwy)) + 
  geom_point() + 
  # Add labels for only the highlighted cars
  geom_label(data = highlight_cars, aes(label = model))

For annotations not tied to specific data points, the annotate() function is your best friend. It lets you add a single geom, like a piece of text, a rectangle, or a line segment, by specifying its position manually.

For example, you could add a text label to explain a cluster of points or draw a rectangle to highlight an area of the plot where fuel efficiency is particularly low.

ggplot(mpg, aes(x = displ, y = hwy)) + 
  geom_point() + 
  # Highlight the low-efficiency zone
  annotate("rect", xmin = 5, xmax = 7.5, 
           ymin = 10, ymax = 20, 
           alpha = 0.2, fill = "red") + 
  # Add a text explanation
  annotate("text", x = 6.25, y = 22, 
           label = "Large engines, low efficiency")

Polishing Your Plot with Themes

The final step in creating a great visualization is refining its appearance. The default ggplot2 style is clean and recognizable, but you can tailor every single visual element, from the background color to the font of the axis labels.

ggplot2 comes with several complete themes that change the overall look with one command. Some popular ones are theme_bw(), theme_minimal(), and theme_classic(). Try adding one to your plot to see the effect.

ggplot(mpg, aes(x = class, y = hwy, fill = class)) + 
  geom_boxplot() + 
  labs(title = "Highway MPG by Car Class") + 
  # Apply a minimal theme
  theme_minimal()

For complete control, you use the theme() function. This function takes dozens of arguments, called theme elements, that let you tweak individual parts of the plot. You can change fonts (element_text()), lines (element_line()), and backgrounds (element_rect()). A common task is to adjust the plot title or remove the legend.

ggplot(mpg, aes(x = class, y = hwy, fill = class)) + 
  geom_boxplot() + 
  labs(title = "Highway MPG by Car Class") + 
  theme_bw() + 
  theme(
    # Center the title and make it bold
    plot.title = element_text(hjust = 0.5, face = "bold"), 
    # Hide the legend since it's redundant
    legend.position = "none",
    # Rotate x-axis labels for readability
    axis.text.x = element_text(angle = 45, hjust = 1)
  )

By combining faceting, annotating, and theming, you can move beyond default settings to create graphics that are not only accurate but also clear, insightful, and aesthetically pleasing. These advanced techniques are the key to effective data storytelling.

Quiz Questions 1/6

Which ggplot2 function is best suited for creating a grid of subplots based on the values of a single categorical variable?

Quiz Questions 2/6

You want to add a text label to your plot to highlight a specific region, located at coordinates x=2010 and y=50. This label is not associated with any specific point in your original dataset. Which function should you use?