8: Layers & Aesthetics
Content for Wednesday, April 22, 2026
Before class
📖 Reading:
During class
We’ll cover:
- Matching geom to data type — a decision guide
- Distributions:
geom_histogram()vsgeom_density() - Comparing groups:
geom_boxplot()vsgeom_violin() stat_summary()— means, error bars, and custom functions- What SE, SD, and CI error bars actually mean
- Position adjustments: dodge, stack, fill, jitter
- Scales: controlling axes, colors, and legends
coord_flip()vscoord_cartesian()— and why they’re different
Slides
View slides in new tab Download PDFEmbedded slides
After class
✅ Practice:
- Create a histogram and a density plot of the same variable. When does each one work better?
- Make a boxplot and a violin plot side by side for the same data. What does the violin show that the boxplot hides?
- Build a bar chart with error bars using
stat_summary(). Try bothmean_seandmean_cl_normal— what changes? - Practice
position = "dodge"with a grouped bar chart - Try
coord_flip()on a plot with long category labels — does it help readability?
Notecoord_cartesian() vs scale limits
These do very different things:
# This ZOOMS — all data is still used for calculations
coord_cartesian(ylim = c(400, 600))
# This DROPS data outside the range — changes your summaries!
scale_y_continuous(limits = c(400, 600))Use coord_cartesian() when you want to zoom in. Use scale limits only when you actually want to exclude data.
Psychology application: error bars
# The standard psych figure: mean + SE + individual points
data |>
ggplot(aes(x = condition, y = score, fill = condition)) +
geom_jitter(width = 0.2, alpha = 0.4) +
stat_summary(fun = mean, geom = "bar", alpha = 0.6, width = 0.5) +
stat_summary(fun.data = mean_se, geom = "errorbar", width = 0.2) +
labs(caption = "Error bars = SE of the mean.")