R ggplot2 — The Grammar of Graphics
Learning Objectives
By the end of this tutorial, you will be able to:
- Build plots layer by layer using the grammar of graphics
- Create scatter plots, bar charts, histograms, and boxplots
- Customize aesthetics, scales, and themes
- Add annotations, labels, and facets
- Create publication-quality visualizations
The Grammar of Graphics
ggplot2 builds plots in layers:
library(ggplot2)
# Basic structure
ggplot(data, aes(x, y)) +
geom_*() +
scale_*() +
labs() +
theme()
| Component | Description |
|---|---|
| Data | The dataset |
| Aesthetics | Mapping: x, y, color, size, shape |
| Geometries | Visual marks: points, lines, bars |
| Facets | Subplots by groups |
| Scales | Map data to visual properties |
| Coordinates | Coordinate system |
| Themes | Non-data visual elements |
Basic Plots
Scatter Plot
ggplot(mtcars, aes(x = wt, y = mpg)) +
geom_point()
# With color and size
ggplot(mtcars, aes(x = wt, y = mpg, color = factor(cyl), size = hp)) +
geom_point(alpha = 0.7) +
labs(title = "Car Weight vs MPG", color = "Cylinders", size = "Horsepower")
Bar Chart
# Count
ggplot(mtcars, aes(x = factor(cyl))) +
geom_bar(fill = "steelblue")
# Values
ggplot(mtcars, aes(x = factor(cyl), y = mpg)) +
geom_col(fill = "steelblue")
# Stacked
ggplot(mtcars, aes(x = factor(cyl), fill = factor(gear))) +
geom_bar(position = "stack")
# Grouped
ggplot(mtcars, aes(x = factor(cyl), fill = factor(gear))) +
geom_bar(position = "dodge")
Histogram
ggplot(mtcars, aes(x = mpg)) +
geom_histogram(bins = 20, fill = "steelblue", color = "white")
# Density
ggplot(mtcars, aes(x = mpg)) +
geom_density(fill = "steelblue", alpha = 0.5)
Boxplot
ggplot(mtcars, aes(x = factor(cyl), y = mpg)) +
geom_boxplot(fill = "steelblue")
# Violin + Boxplot
ggplot(mtcars, aes(x = factor(cyl), y = mpg)) +
geom_violin(fill = "steelblue", alpha = 0.5) +
geom_boxplot(width = 0.1)
Line Plot
# Time series
ggplot(economics, aes(x = date, y = unemploy)) +
geom_line(color = "steelblue") +
labs(title = "US Unemployment Over Time")
Aesthetics Mapping
# Color
ggplot(mtcars, aes(x = wt, y = mpg, color = factor(cyl))) +
geom_point()
# Fill
ggplot(mtcars, aes(x = factor(cyl), fill = factor(cyl))) +
geom_bar()
# Size
ggplot(mtcars, aes(x = wt, y = mpg, size = hp)) +
geom_point(alpha = 0.5)
# Shape
ggplot(mtcars, aes(x = wt, y = mpg, shape = factor(cyl))) +
geom_point()
# Alpha (transparency)
ggplot(mtcars, aes(x = wt, y = mpg)) +
geom_point(alpha = 0.3)
# Manual aesthetics (not mapped from data)
ggplot(mtcars, aes(x = wt, y = mpg)) +
geom_point(color = "red", size = 3, shape = 16)
Geometric Objects
Common Geoms
# Points
geom_point()
# Lines
geom_line()
geom_path()
# Bars
geom_bar()
geom_col()
# Histograms
geom_histogram()
geom_density()
# Boxplots
geom_boxplot()
geom_violin()
# Error bars
geom_errorbar()
geom_pointrange()
# Text
geom_text()
geom_label()
# Smooth
geom_smooth(method = "lm")
geom_smooth(method = "loess")
# Jitter
geom_jitter()
Combining Geoms
ggplot(mtcars, aes(x = wt, y = mpg)) +
geom_point() +
geom_smooth(method = "lm", se = FALSE)
ggplot(mtcars, aes(x = wt, y = mpg)) +
geom_point(alpha = 0.5) +
geom_smooth(method = "lm", color = "red")
Facets
# Facet by single variable
ggplot(mtcars, aes(x = wt, y = mpg)) +
geom_point() +
facet_wrap(~cyl)
# Facet by two variables
ggplot(mtcars, aes(x = wt, y = mpg)) +
geom_point() +
facet_grid(gear ~ cyl)
# Free scales
ggplot(mtcars, aes(x = wt, y = mpg)) +
geom_point() +
facet_wrap(~cyl, scales = "free")
# Labeller
ggplot(mtcars, aes(x = wt, y = mpg)) +
geom_point() +
facet_wrap(~cyl, labeller = label_both)
Scales
# Continuous scales
ggplot(mtcars, aes(x = wt, y = mpg)) +
geom_point() +
scale_x_continuous(limits = c(0, 6), breaks = seq(0, 6, 1)) +
scale_y_continuous(limits = c(0, 40), breaks = seq(0, 40, 10))
# Log scale
ggplot(mtcars, aes(x = wt, y = mpg)) +
geom_point() +
scale_x_log10() +
scale_y_log10()
# Color scales
ggplot(mtcars, aes(x = wt, y = mpg, color = factor(cyl))) +
geom_point() +
scale_color_manual(values = c("4" = "red", "6" = "blue", "8" = "green"))
# Viridis
ggplot(mtcars, aes(x = wt, y = mpg, color = hp)) +
geom_point() +
scale_color_viridis_c()
# Brewer
ggplot(mtcars, aes(x = wt, y = mpg, color = factor(cyl))) +
geom_point() +
scale_color_brewer(palette = "Set1")
Labels and Annotations
# Labels
ggplot(mtcars, aes(x = wt, y = mpg)) +
geom_point() +
labs(
title = "Car Weight vs MPG",
subtitle = "From mtcars dataset",
x = "Weight (1000 lbs)",
y = "Miles per Gallon",
caption = "Data from R datasets"
)
# Annotations
ggplot(mtcars, aes(x = wt, y = mpg)) +
geom_point() +
annotate("text", x = 5, y = 35, label = "Some text") +
annotate("rect", xmin = 3, xmax = 5, ymin = 15, ymax = 25, alpha = 0.2) +
annotate("segment", x = 2, xend = 4, y = 10, yend = 20, color = "red")
Themes
# Built-in themes
ggplot(mtcars, aes(x = wt, y = mpg)) +
geom_point() +
theme_minimal()
ggplot(mtcars, aes(x = wt, y = mpg)) +
geom_point() +
theme_bw()
ggplot(mtcars, aes(x = wt, y = mpg)) +
geom_point() +
theme_classic()
# Custom theme
ggplot(mtcars, aes(x = wt, y = mpg)) +
geom_point() +
theme(
plot.title = element_text(size = 16, face = "bold"),
axis.title = element_text(size = 12),
legend.position = "bottom",
panel.grid.minor = element_blank()
)
# ggrepel for non-overlapping labels
library(ggrepel)
ggplot(mtcars, aes(x = wt, y = mpg, label = rownames(mtcars))) +
geom_point() +
geom_text_repel()
Save Plots
# Save last plot
ggsave("plot.png", width = 8, height = 6, dpi = 300)
ggsave("plot.pdf", width = 8, height = 6)
ggsave("plot.svg", width = 8, height = 6)
Practical Examples
Example 1: Dashboard Plot
library(dplyr)
library(ggplot2)
# Create plot
p <- mtcars |>
mutate(cyl = factor(cyl)) |>
ggplot(aes(x = wt, y = mpg, color = cyl, size = hp)) +
geom_point(alpha = 0.7) +
geom_smooth(method = "lm", se = FALSE, linetype = "dashed") +
labs(
title = "Car Performance Analysis",
subtitle = "Weight vs Fuel Efficiency",
x = "Weight (1000 lbs)",
y = "Miles per Gallon",
color = "Cylinders",
size = "Horsepower"
) +
theme_minimal() +
theme(
plot.title = element_text(face = "bold"),
legend.position = "right"
)
ggsave("car_analysis.png", p, width = 10, height = 6)
Practice Exercises
Exercise 1: Diamond Prices
Create a visualization of diamond prices by cut, colored by clarity.
Solution
library(ggplot2)
ggplot(diamonds, aes(x = cut, y = price, fill = clarity)) +
geom_boxplot() +
labs(
title = "Diamond Prices by Cut and Clarity",
x = "Cut",
y = "Price ($)"
) +
theme_minimal()
Key Takeaways
- ggplot2 builds plots in layers — data, aesthetics, geometry, scales, themes
aes()maps data to visual properties — x, y, color, size, shape- Geoms determine plot type — point, bar, line, histogram, boxplot
- Facets create subplots —
facet_wrap()andfacet_grid() - Scales control mapping — continuous, discrete, color, size
- Themes control appearance — fonts, gridlines, legends
- Use
ggsave()to save — PNG, PDF, SVG formats
Next: Learn about R Statistical Functions — descriptive statistics.