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”.

Back to top