
Session 2 · Grammar of Graphics — Aesthetics, Geoms & Facets
2026-07-21
ggplot(data, aes(x, y)) + geom_...()Recreate this from memory (don’t peek at Session 1 notes yet!):
A scatter plot of
bill_length_mm(x) vsbill_depth_mm(y), coloured byspecies.
| Time | Topic |
|---|---|
| 0–10 min | Recap + more aesthetics (size, shape, alpha) |
| 10–25 min | Trend lines with geom_smooth() |
| 25–45 min | Distributions: histograms & density plots |
| 45–65 min | Comparing groups: boxplots |
| 65–85 min | Facets — small multiples |
| 85–90 min | Wrap-up |
Aesthetics aren’t limited to x, y, and color. We can also map data to:
size — bigger/smaller pointsshape — different point symbolsalpha — transparency (0 = invisible, 1 = solid)Notice: alpha = 0.6 is set outside aes(), directly inside geom_point(). That’s because we’re not mapping it to a variable — we’re setting one fixed value for every point. This is a key distinction in ggplot2.
Inside aes() |
Outside aes() |
|---|---|
| Value comes from a column in your data | Value is the same for every point |
aes(color = species) |
color = "steelblue" |
aes(size = bill_length_mm) |
size = 3 |
| Varies per row | Fixed by you |
bill_length_mm vs bill_depth_mmshape to speciesalpha = 0.5 and size = 2 (not mapped — just typed directly)geom_smooth()Two geoms, one plot — this is layering. geom_smooth() fits a curve through the data (a “loess” curve by default) with a shaded confidence band.
method = "lm" fits a straight linear model instead of a curve — useful when you specifically want to show a linear relationship.
Because color = species was set in the shared aes(), both geom_point() and geom_smooth() inherit it — giving us one trend line per species automatically!
Plot bill_length_mm (x) vs bill_depth_mm (y):
species"lm") trend line — one per speciesWhat do you notice about the overall trend vs. each species’ trend? (This is a classic case of Simpson’s Paradox!)
R gives a friendly warning about bin count — histograms group numeric values into bins and count how many rows fall in each.
binwidth → more detail, more noisebinwidth → smoother, but may hide real patternsposition = "identity" lets the three histograms overlap rather than stack — combined with alpha, we can see all three at once.
A density plot is like a smoothed histogram — useful for comparing shapes of distributions across groups without worrying about binwidth.
flipper_length_mm with binwidth = 5species, with alpha = 0.6 and position = "identity"Reading a boxplot:
Adding fill = species is slightly redundant with x = species here, but it makes group boundaries easier to see at a glance, especially in printed handouts.
geom_jitter() nudges overlapping points sideways randomly so we can see individual data — this shows both the summary (boxplot) and the raw data (jittered points) together.
Make a boxplot of flipper_length_mm by species, filled by species, with jittered points on top.
facet_wrap() — one variableThe ~species means “split by species.” Each panel shows the same x/y axes, just filtered to one species’ data.
facet_grid() — two variables at oncefacet_grid(rows ~ columns) creates a full grid: rows = sex, columns = species. Great for comparing two categorical variables simultaneously. (Note: a few penguins have missing sex — we’ll handle missing data more in Session 3.)
Facets and aesthetics work together nicely — here we see, per island, how species separate by bill measurements.
body_mass_gspecies using facet_wrap()sex using facet_grid(sex ~ species)aes() vary by data; values set outside aes() are fixedgeom_smooth() adds trend lines — watch for group-level reversals (Simpson’s Paradox!)geom_histogram() / geom_density() show the shape of one numeric variablegeom_boxplot() compares a numeric variable across groups; geom_jitter() shows raw data on topfacet_wrap(~var) and facet_grid(row ~ col) split one plot into small multiplesPractice at home:
Next session: Titles & labels, themes, custom colour palettes, coord_flip(), and — crucially — saving your plots with ggsave() so they’re ready for your paper, poster, or presentation.
Session 2 complete 🎉
SARA Institute of Data Science — building open, first-generation, Ambedkarite research capacity, one dataset at a time.
SARA Institute of Data Science · R for Researchers