Session 5: Data Visualization I — the Grammar of Graphics

Published

26 10 2026

Modified

16 10 2026

Note

Monday, 26 October 2026, 09:00–11:15 · Room MAD 099

What this session is about

You have been reading charts for years. In Statistik I and II you never had to build one — and that is the first thing in this course you genuinely have not done before.

The good news is that every chart you will ever make in R is put together from the same handful of parts. A chart is a mapping: this column goes on the x axis, that one on the y axis, a third one decides the colour. Once you can say that sentence, the code follows from it almost word for word. That idea has a name — the grammar of graphics — and it is what ggplot2 is built on.

The other half of the session is choosing. A histogram, a boxplot, a scatter plot and a line chart answer different questions, and most bad charts are not ugly — they are answers to a question nobody asked. So today every chart starts from a question, never from a chart type.

We do this on new data: hotel prices in 46 European cities, which arrive in two files that have to be joined before you can draw anything at all. And the prices are so spread out that the ordinary axis you have used so far stops working — which is where the logarithmic scale, promised since session 1, finally comes in.

ImportantPackages you need today

Nothing new to install. ggplot2 and forcats come with the tidyverse, and scales — which formats axis labels as euros — is installed along with it:

library(tidyverse)
library(scales)
library(here)

Learning goals

  • Describe any chart as a mapping from columns to visual properties, in one sentence, before writing code
  • Name the parts of a ggplot — data, aesthetics, geoms, scales, facets — and say which line of code is which
  • Choose a chart from the question: one distribution, a comparison between groups, a relationship between two numbers, a change over time
  • Explain why position is read more accurately than colour or area, and what that means for the charts you choose
  • Use a logarithmic axis when the data calls for it, read one correctly, and label it in euros rather than in logarithms
  • Show a third variable with colour or with facets, and decide which
  • Tell mapping a property (aes(colour = city)) from setting it (colour = "steelblue") — the most common ggplot bug there is
  • Join two tables before plotting, and check n on the way

Slides

The slides appear here after the session.

Everything you need for the session is already below.

Materials

File Description
Exercise sheet The in-session exercise
hotels-europe_price.csv Prices: one row per hotel and date
hotels-europe_features.csv Features: one row per hotel
Slides Online after the session
Live coding document Online after the session
Exemplary solution Online after the session

Data

Hotels in Europe — the bigger sibling of the Vienna data you used in sessions 1 to 3, collected the same way from a price comparison website: 22,902 properties in 46 cities, each priced on up to ten different dates between November 2017 and June 2018.

It comes in two files, and neither is enough on its own:

File One row is… Key columns
hotels-europe_price.csv one hotel on one date hotel_id, price, year, month, weekend, nnights
hotels-europe_features.csv one hotel hotel_id, city, distance, stars, rating, accommodation_type

The price file knows what a room costs but not where the hotel is; the features file knows where it is but not what it costs. hotel_id is the column they share. That is the join session 2 promised you would need.

Békés and Kézdi (2021), licensed CC BY-NC-SA 4.0. Unmodified.

price is the price for the whole stay, and not every stay is one night. Some December rows are four-night stays, so their price is roughly four times a nightly one. Put all rows into one chart and you are comparing two different units without knowing it.

This is not hidden — it is what the nnights column is for. Today’s exercise works with a single date and a single night throughout, which makes the problem go away. One of the optional tasks asks you to find it the hard way.

The questions we answer

A hotel group that so far only knows Vienna wants to understand the European market. The board has four questions, and each one needs a different chart:

  1. What does a night in a European hotel typically cost — and is “typical” even a useful word here?
  2. Which cities are cheap, which are expensive, and by how much?
  3. Do central hotels charge more everywhere, or only in some cities?
  4. When in the year is a weekend city break cheapest?

The first question breaks the axis. Prices run from a few euros to several thousand, so on an ordinary axis almost every hotel is squeezed into one bar on the far left. On a logarithmic axis the same data turns into a clean, readable hump — and the answer to “how much more expensive is Stockholm than Istanbul?” becomes a question about ratios, which is the question people were asking all along.

The third question is where the grammar pays off: one extra line of code, facet_wrap(~ city), turns one unreadable chart into eight readable ones — and shows that “central hotels charge more” is true, but by very different amounts in different places.

Take-home until session 6

Important
  1. Finish the exercise, including the reverse-engineering task — it is the best test of whether the grammar has landed
  2. Read Wickham et al. (2023), ch. 1 “Data visualization” if you have not, and ch. 9 “Layers” — together about an hour, and they cover everything we did today
  3. Skim Healy (2018), ch. 1 “Look at data”. It is the argument behind session 6.

Session 6 turns from building charts to communicating with them: titles that state a finding, labels, colour that carries meaning — and the charts that mislead, whether by accident or on purpose. Report 2 is issued at the end of it, and is submitted through GitHub.

Going further

  • Wickham et al. (2023), ch. 1, 9, 10 and 11 — visualization, layers, exploratory analysis, communication
  • Healy (2018) — the best book-length introduction to ggplot2 for social scientists, free online
  • Wilke (2019) — which chart for which question, with many good and bad examples side by side. Free online.
  • Wickham (2010) — the paper behind ggplot2, if you want to see where the grammar comes from
  • The ggplot2 cheat sheet — worth printing

References

Békés, G. and Kézdi, G. (2021) Data analysis for business, economics, and policy, Cambridge: Cambridge University Press, available at https://gabors-data-analysis.com/.
Healy, K. (2018) Data visualization: A practical introduction, Princeton: Princeton University Press, available at https://socviz.co/.
Wickham, H. (2010) “A layered grammar of graphics,” Journal of Computational and Graphical Statistics 19(1): 3–28.
Wickham, H., Çetinkaya-Rundel, M. and Grolemund, G. (2023) R for data science: Import, tidy, transform, visualize, and model data, 2nd edition., Beijing et al.: O’Reilly, available at https://r4ds.hadley.nz/.
Wilke, C. O. (2019) Fundamentals of data visualization, Sebastopol, CA: O’Reilly, available at https://clauswilke.com/dataviz/.