Aesthetics vs. Geoms
You have just seen that a plot needs both a mapping (aes()) and a geometry (geom_*()). We discuss these ingredients now in more detail.
Adding more aesthetics
Aesthetic mappings aren’t limited to x and y. You can map a third variable onto colour, shape, size, and more.
Do: run the scatterplot below.
Predict: what do you think will happen if you add colour = class inside the aes() call?
See: each point is now coloured according to the car’s vehicle class, and a legend appears automatically.
Explain: mapping a variable to an aesthetic tells ggplot2: “the value of this variable should determine the appearance of each observation.” Because class is categorical, ggplot2 picks a discrete colour for each level and builds the legend for you, you don’t have to specify the colours yourself.
Combining multiple geoms
Layers stack with +, so you can combine several geometries in a single plot — each one reusing the same underlying data and mapping unless you override it.
Do: run the following, which layers a smoothed trend line on top of the points.
See: both the raw points and a smoothed curve (with a grey confidence band) appear in the same plot.
Explain: because we supplied the mapping to ggplot() directly (rather than to an individual geom_*()), both geom_point() and geom_smooth() inherit that mapping. This saves you from repeating aes(x = displ, y = hwy) in every layer. You can still override or add to the inherited mapping for a single layer if you need to, by supplying aes() again inside that specific geom_*() call — as you did in the exercises above.
Common mistake: putting aes() on the wrong layer
Because mappings set in ggplot() are inherited by every layer, a common mistake is putting the mapping on just one geom_*() instead, forgetting that other layers won’t automatically know about it.
Do: run the following, which looks like it should draw points with a trend line on top, similar to what you just saw above.
See: nothing is plotted at all, not even the points. Instead you get an error.
Predict: look closely at where aes(x = displ, y = hwy) is written in the code above. Based on that, why do you think geom_smooth() didn’t draw anything?
Explain: here, aes(x = displ, y = hwy) was supplied only to geom_point(), not to ggplot() itself. That means geom_point() knows which variables to use, but geom_smooth() doesn’t inherit that mapping from anywhere else, so it has no x or y to work with and can’t draw a line. Each layer only uses the mapping it’s given directly, plus whatever was set in ggplot(); it does not pick up a mapping from another layer. To have every layer share a mapping, it needs to go in ggplot(mapping = aes(...)), as you did earlier in “Combining multiple geoms”.