Where We Are Starting From

Please complete the Student Voice section on NOW.

Weeks 2 To 5 Build One Workflow

  • Week 2: Principles of data visualisation
  • Week 3: Grammar of graphics; aesthetics and attributes
  • Week 4: Major visualisation tools
  • Week 5: Customising visualisations (scales, themes, and labels)

What Week 5 Adds

By the end of this session, you should be able to:

  1. Improve ggplot2 visualisations using labels, legends, colour, and simple themes.
  2. Choose aesthetics and scales that fit the variable type and comparison.
  3. Decide which customisation improves clarity, and which is only decoration.
  4. Start a formative assessment RMarkdown using either the provided dataset or your own dataset.

Download the Week 5 files from NOW. Unzip the folder, then move the unzipped Week 5 folder into your existing RStudio Project folder.

Today: Practical Scope

The session has two practical blocks.

Block Main work Files
1 Make plots easier to understand with labels, legends, colour, and aesthetics. 01_labels_and_legends.Rmd
02_colours_and_aesthetics.Rmd selected parts
2 Start a formative assessment figure and decide what the plot should show. 04_formative_practice_provided_data.Rmd
or 05_formative_planning_own_data.Rmd

03_themes.Rmd is optional/homework/reference material for after the session.

The priority today is not to try every customisation option. It is to make better decisions about which changes help the viewer.

Discussion: What Helps You Read This Chart?

Variable Type Also Guides Aesthetics

In Week 4, variable type helped us choose geoms. In Week 5, it helps us choose aesthetics and scales.

Variable type Good aesthetic choices Be careful with
categorical groups colour, fill, shape, linetype, facets too many colours or shapes
ordered categories ordered colour, position, facets unordered palettes
continuous values position, colour gradient, size size can be hard to compare
binary variables colour, shape, linetype redundant legends

Aesthetic mappings should make the important comparison easier, not just make the plot more colourful.

Customisation Serves The Comparison

Customisation should help the viewer answer the question.

Customisation Helps the viewer… Ask yourself…
labels know what the variables, units, and groups mean could this plot stand alone in a report?
legends and facets understand which observations belong to which group are the group names meaningful?
colour and aesthetics compare categories, ordered values, or continuous values does the aesthetic fit the variable type?
scales read values fairly and accurately could the scale mislead the comparison?
themes remove unnecessary distraction did this remove clutter or add decoration?
export choices make the figure readable at final size are text, points, and aspect ratio still clear?

Week 5 is about defensible visualisation choices, not polishing plots for its own sake.

Customisation Applies Visualisation Principles

Tufte’s principles are not just about making sparse plots. They ask whether every visible element helps the viewer understand the data.

Principle What customisation can do Example Week 5 choice
increase data-ink make the data easier to see than the decoration lighten or remove heavy grid lines
reduce chartjunk remove marks that do not support the comparison avoid decorative themes and unnecessary colours
support comparison keep related plots comparable use consistent scales, facets, and labels
guide interpretation help viewers notice the intended pattern use titles, subtitles, captions, and direct labels
avoid distortion make readings fair and transparent choose appropriate axes, scales, and grouping aesthetics

Customising a plot is an argument about what matters in the data.

Design Choices Should Reduce Distraction

Revisiting Tufte’s Principles (Tufte, 2001):

  • Data-ink ratio: make the data marks more prominent than the supporting marks.
  • Chartjunk: remove decoration that does not help the comparison.
  • Small multiples: use consistent scales and layouts so groups can be compared fairly.
  • Narrative graphics: use text, annotations, and labels to guide interpretation.

The point is not that every plot should be minimal. The point is that every customisation should earn its place.

Tufte Ideas Become ggplot2 Decisions

In ggplot2, these principles become specific choices we can make and justify.

Tufte principle ggplot2 decision
increase data-ink use quiet themes, lighter grids, and visible data marks
reduce chartjunk avoid decorative palettes, heavy backgrounds, and unnecessary legends
support comparison use facets, consistent scales, and aligned axes
guide interpretation write meaningful titles, axis labels, legend labels, and captions
avoid distortion choose sensible scales, transparency, jittering, or grouping aesthetics

The grammar of graphics helps because each layer can be changed deliberately: data, mapping, geom, scale, coordinate system, facet, and theme.

Labels Make Plots Stand Alone

  • title
  • subtitle
  • caption
  • tag
  • x
  • y
  • colour, shape, linetype, fill
ggplot(d_spellname, aes(y = rt,
    x = dur,
    colour = modality)) +
  geom_point() + 
  labs()

Titles Should Name The Comparison

  • title
  • subtitle
  • caption
  • tag
  • x
  • y
  • colour, shape, linetype, fill
ggplot(d_spellname, aes(y = rt,
    x = dur,
    colour = modality)) +
  geom_point() + 
  labs(title =
    "Reaction time and duration")

Subtitles Add Context

  • title
  • subtitle
  • caption
  • tag
  • x
  • y
  • colour, shape, linetype, fill
ggplot(d_spellname, aes(y = rt,
    x = dur,
    colour = modality)) +
  geom_point() + 
  labs(title =
    "Reaction time and duration",
       subtitle = "Participant-level averages")

Captions Tell Readers Where Data Came From

  • title
  • subtitle
  • caption
  • tag
  • x
  • y
  • colour, shape, linetype, fill
ggplot(d_spellname, aes(y = rt,
    x = dur,
    colour = modality)) +
  geom_point() + 
  labs(caption = "Data: picture naming norms")

Tags Can Label Panels

  • title
  • subtitle
  • caption
  • tag
  • x
  • y
  • colour, shape, linetype, fill
ggplot(d_spellname, aes(y = rt,
    x = dur,
    colour = modality)) +
  geom_point() + 
  labs(tag = "A")

Axis Labels Need Units

  • title
  • subtitle
  • caption
  • tag
  • x
  • y
  • colour, shape, linetype, fill
ggplot(d_spellname, aes(y = rt,
    x = dur,
    colour = modality)) +
  geom_point() + 
  labs(x = "Production duration (ms)",
       y = "Reaction time (ms)")

Legend Titles Name The Grouping

  • title
  • subtitle
  • caption
  • tag
  • x
  • y
  • colour, shape, linetype, fill
ggplot(d_spellname, aes(y = rt,
    x = dur,
    colour = modality)) +
  geom_point() + 
  labs(colour = "Response mode")

Exercise 1: Changing Text

Open 01_labels_and_legends.Rmd.

Complete Tasks 1-3 (about 12 minutes): choose axis labels, improve the legend, and write a title.

Keep one labelled figure and one sentence explaining your choice.

Stop at “In-class stopping point”. The remaining label examples are optional.

Colour: Hue Versus Brightness

Colour can represent different kinds of information.

Colour property Best for Example
Hue categories speech vs writing
Brightness / lightness ordered or continuous values low to high vocabulary
Diverging colour values around a meaningful midpoint below vs above average

Use different hues for different kinds of things. Use light-to-dark progressions for more/less.

Colour Scales Change Values And Labels

  • scale_colour_discrete
  • scale_colour_continuous
  • scale_colour_manual
  • or any other aesthetic instead of colour
ggplot(d_spellname, aes(y = rt,
    x = dur,
    colour = modality)) +
  geom_point() +  
  scale_colour_discrete(
    labels = c("Spoken output",
               "Written output")) 

Existing Palette Functions Are The Easiest Start

  • Use a palette function first
  • ggthemes::scale_colour_colorblind()
  • Then customise manually only when needed
ggplot(d_spellname, aes(y = rt,
    x = dur,
    colour = modality)) +
  geom_point() +  
  scale_colour_colorblind(
    labels = c("Spoken output",
               "Written output"))

Manual Colours Should Support Comparison

  • Change colour values manually
  • Colour names: link
  • ggthemes
ggplot(d_spellname, aes(y = rt,
    x = dur,
    colour = modality)) +
  geom_point() +  
  scale_colour_manual(
    labels = c("Spoken output",
               "Written output"),
    values = c("#0072B2", "#D55E00"))

Store Palette Values When You Need Manual Control

  • Start from a tested palette
  • Store hex codes if you need to reuse them
  • scales::show_col() previews colours
# RGB codes of "colorblind" function
mycolours <- c("#000000", "#E69F00",
               "#56B4E9", "#009E73",
               "#F0E442", "#0072B2",
               "#D55E00", "#CC79A7")

# RGB codes of "colorblind" function
scales::show_col(colorblind_pal()(8))

Legend Labels Should Be Human-Readable

  • Replace data codes with readable group names
  • labels changes the legend wording
  • values controls the corresponding colours
ggplot(d_spellname, aes(y = rt,
    x = dur,
    colour = modality)) +
  geom_point() +  
  scale_colour_manual(
    labels = c("Spoken output",
               "Written output"),
    values = mycolours[1:2])

Discussion: Colour, Shape, Or Facets?

Each version shows the same relationship. Which would you use, and what trade-off does it make?

When does another aesthetic help, and when does it become clutter?

Exercise 2: Colour And Aesthetic Decisions

Open 02_colours_and_aesthetics.Rmd.

Complete Tasks 1-2 (about 12 minutes): choose a palette and compare overlapping age distributions.

Record which version you would use and what the viewer can compare more easily.

Stop at “In-class stopping point”. Manual palette exploration is optional.

Facet Strips Are Labels Too

ggplot(d_spellname, aes(y = rt,
    x = dur)) +
  geom_point() + 
  facet_grid(~modality)

Facet Labels Can Come From The Data

ggplot(d_spellname, aes(y = rt,
    x = dur)) +
  geom_point() + 
  facet_grid(~modality,
             labeller = label_both)

Recoding Changes The Data Labels

d_spellname <- mutate(d_spellname,
  modality = recode(modality,
    speech = "Spoken output",
    writing = "Written output"))

ggplot(d_spellname, aes(x = dur, y = rt)) +
  geom_point() +
  facet_grid(~modality)

Strip Labels Should Match The Story

ggplot(d_spellname, aes(y = rt,
    x = dur)) +
  geom_point() + 
  facet_grid(~modality, labeller = label_both)

Themes Control Non-Data Ink

Start with a complete theme, then change individual elements with theme().

Complete theme Starting appearance
theme_grey() grey panel and white grid lines
theme_bw() white panel, grid lines, and a border
theme_classic() axis lines without grid lines
theme_minimal() grid lines without a panel background
theme_light() light grid lines and a border
theme_dark() dark panel and lighter grid lines

ggthemes adds starting points such as theme_clean() and theme_tufte().

Choose a starting point that makes the comparison easy to read.

Start From The ggplot2 Default

ggplot(d_spellname, aes(y = rt,
    x = dur)) + 
  geom_point() +
  facet_grid(~modality) +
  theme_grey(base_size = 11)

theme_minimal(): No Panel Background

ggplot(d_spellname, aes(y = rt,
    x = dur)) + 
  geom_point() +
  facet_grid(~modality) +
  theme_minimal(base_size = 14)

theme_light(): Light Grid And Border

ggplot(d_spellname, aes(y = rt,
    x = dur)) + 
  geom_point() +
  facet_grid(~modality) +
  theme_light(base_size = 14)

theme_dark(): A Dark Panel Background

ggplot(d_spellname, aes(y = rt,
    x = dur)) + 
  geom_point() +
  facet_grid(~modality) +
  theme_dark(base_size = 14)

Theme Packages Add Starting Points

ggplot(d_spellname, aes(y = rt,
    x = dur)) + 
  geom_point() +
  facet_grid(~modality) +
  theme_clean()

Choose Themes For The Comparison

  • axis
  • legend
  • panel
  • plot
  • strip
ggplot(d_spellname, aes(y = rt,
    x = dur)) + 
  geom_point() +
  theme()

Axis Text Is Part Of Readability

  • axis.text
    • axis.text.x
    • axis.text.y
  • axis.title
    • axis.title.x
    • axis.title.y
ggplot(d_spellname, aes(y = rt,
    x = dur)) + 
  geom_point() +
  theme(axis.text = element_text(
    face = "italic"))

Bold Axis Titles Can Add Emphasis

  • axis.text
    • axis.text.x
    • axis.text.y
  • axis.title
    • axis.title.x
    • axis.title.y
ggplot(d_spellname, aes(y = rt,
    x = dur)) + 
  geom_point() +
  theme(axis.title = element_text(
    face = "bold"))

Axis Titles And Tick Labels Are Separate

  • axis.text
    • axis.text.x
    • axis.text.y
  • axis.title
    • axis.title.x
    • axis.title.y
ggplot(d_spellname, aes(y = rt,
    x = dur)) + 
  geom_point() +
  theme(axis.title.y = element_text(
    face = "bold"))

Legends Compete For Plot Space

  • legend.background
  • legend.margin
  • legend.spacing
  • legend.key
  • legend.text
  • legend.title
  • legend.position
  • legend.orientation
  • legend.justification
  • legend.box
ggplot(d_spellname, aes(y = rt,
    x = dur,
    colour = modality)) + 
  geom_point() +
  theme()

Move Legends When Space Is Tight

  • legend.background
  • legend.margin
  • legend.spacing
  • legend.key
  • legend.text
  • legend.title
  • legend.position
  • legend.orientation
  • legend.justification
  • legend.box
ggplot(d_spellname, aes(y = rt,
    x = dur,
    colour = modality)) + 
  geom_point() +
  theme(legend.position = "top")

Align A Top Legend To The Right

  • legend.background
  • legend.margin
  • legend.spacing
  • legend.key
  • legend.text
  • legend.title
  • legend.position
  • legend.orientation
  • legend.justification
  • legend.box
ggplot(d_spellname, aes(y = rt,
    x = dur,
    colour = modality)) + 
  geom_point() +
  theme(legend.position = "top",
        legend.justification = "right")

An Inside Legend Can Cover Data

  • legend.background
  • legend.margin
  • legend.spacing
  • legend.key
  • legend.text
  • legend.title
  • legend.position
  • legend.orientation
  • legend.justification
  • legend.box
ggplot(d_spellname, aes(y = rt,
    x = dur,
    colour = modality)) +
  geom_point() + 
  theme(legend.position = c(.15, .8))

Grid Lines Can Help Or Distract

  • panel.background
  • panel.border
  • panel.spacing
  • panel.grid
    • panel.grid.major
    • panel.grid.minor
ggplot(d_spellname, aes(y = rt,
    x = dur)) +
  geom_point() + 
  theme()

Remove The Panel Background

  • panel.background
  • panel.border
  • panel.spacing
  • panel.grid
    • panel.grid.major
    • panel.grid.minor
ggplot(d_spellname, aes(y = rt,
    x = dur)) +
  geom_point() + 
  theme(panel.background =
        element_blank())

Plot Properties Control The Whole Figure

  • plot.background
  • plot.margin
  • plot.title
  • plot.subtitle
  • plot.caption
  • plot.tag
ggplot(d_spellname, aes(y = rt,
    x = dur)) +
  geom_point() +
  theme()

A Coloured Plot Background Adds Non-Data Ink

  • plot.background
  • plot.margin
  • plot.title
  • plot.subtitle
  • plot.caption
  • plot.tag
ggplot(d_spellname, aes(y = rt,
    x = dur)) +
  geom_point() + 
  theme(plot.background = element_rect(
    fill = "pink"))

Plot Margins Affect Readability

  • plot.background
  • plot.margin
  • plot.title
  • plot.subtitle
  • plot.caption
  • plot.tag
ggplot(d_spellname, aes(y = rt,
    x = dur)) +
  geom_point() + 
  theme(plot.background = element_rect(
    fill = "pink"),
  plot.margin = unit(c(2, 2, 2, 2),
                     "cm"))

Title Colour Can Help Or Hinder Readability

  • plot.background
  • plot.margin
  • plot.title
  • plot.subtitle
  • plot.caption
  • plot.tag
ggplot(d_spellname, aes(y = rt,
    x = dur)) +
  geom_point() + 
  labs(title = "I'm a title") +
  theme(plot.title = element_text(
    colour = "pink"))

Caption Text Can Be Styled Separately

  • plot.background
  • plot.margin
  • plot.title
  • plot.subtitle
  • plot.caption
  • plot.tag
ggplot(d_spellname, aes(y = rt,
    x = dur)) +
  geom_point() + 
  labs(caption = "I'm a caption") +
  theme(plot.caption = element_text(
    face = "italic"))

Facet Strips Guide Small Multiples

  • strip.background
  • strip.placement
  • strip.text
ggplot(d_spellname, aes(y = rt,
    x = dur)) +
  geom_point() + 
  facet_grid(~modality,
             labeller = label_both) +
  theme()

Strip Backgrounds Can Add Clutter

  • strip.background
  • strip.placement
  • strip.text
ggplot(d_spellname, aes(y = rt,
    x = dur)) +
  geom_point() + 
  facet_grid(~modality,
             labeller = label_both) +
  theme(strip.background =
        element_blank())

Strip Background Colour Changes The Emphasis

  • strip.background
  • strip.placement
  • strip.text
ggplot(d_spellname, aes(y = rt,
    x = dur)) +
  geom_point() + 
  facet_grid(~modality,
             labeller = label_both) +
  theme(strip.background = element_rect(
    fill = "forestgreen"))

Strip Text Needs To Stay Readable

  • strip.background
  • strip.placement
  • strip.text
ggplot(d_spellname, aes(y = rt,
    x = dur)) +
  geom_point() + 
  facet_grid(~modality,
             labeller = label_both) +
  theme(strip.background = element_rect(fill = "forestgreen"),
        strip.text = element_text(colour = "white", hjust = 0))

Combine Theme Changes Deliberately

  • strip.background
  • strip.placement
  • strip.text
ggplot(d_spellname, aes(y = rt,
    x = dur)) +
  geom_point() + 
  facet_grid(~modality,
             labeller = label_both)+
  theme(strip.background = element_rect(fill = "forestgreen"),
        strip.text = element_text(colour = "white", hjust = 0, 
            face = "bold", size = 16, angle = 180))

Optional/Homework: Themes

03_themes.Rmd is optional/homework/reference material.

If you have time, use it to compare themes and choose a quiet starting point for an assessment-style figure. The aim is not to design a personal style from scratch during class.

Useful Resources For Data Visualisation

Recommended Reading

Start The Formative Figure

This is the main second-block task. Use one of the two templates in the Week 5 files:

  • 04_formative_practice_provided_data.Rmd if you want to practise with the provided Blomkvist dataset.
  • 05_formative_planning_own_data.Rmd if you already have a candidate dataset.

Start by deciding what your first figure should help the viewer compare.

Use the next 25 minutes to:

  • Choose one question and draft one figure.
  • Give the document a title about your data or question.
  • Give the figure section a heading about the comparison.
  • Add a caption and explain one design choice in 2-3 sentences.

You can run chunks while developing the figure.

Formative Assessment: The Full Brief

Select a behavioural dataset, such as reaction times, survey responses, or decision-making data.

  • Create 3-4 visualisations using different techniques (e.g., boxplot, scatterplot, density plot).
  • Include brief commentary on:
    • What each visualisation highlights about the data?
    • Why each visualisation was chosen?
    • How each visualisation adheres to principles of effective visualisation (e.g., Tufte’s guidelines)?
    • What each visualisation may obscure about the data.
  • Deadline: Friday 30 October 2026, before 2 pm
  • Length: max 1,000 words

Feedback focus:

  • Clarity and effectiveness of visualisations.
  • Code quality and reproducibility.
  • Interpretation and communication of behavioural insights.

Explain The Choice In Your Own Figure

Choose one or two decisions in your figure. Explain how they help answer your question and what the figure still hides.

Decision Options you could compare
Showing variation raw points, a summary, or both
Distinguishing groups colour, colour and shape, or separate facets
Showing overlap opaque fill, transparent fill, or outlines
Making text useful variable names or descriptive labels with units; a question or finding as the title
Keeping useful structure keep, lighten, or remove grid lines; choose a starting theme

Example: “I used transparent fills so the overlapping age distributions remain visible, but the curves do not show how many participants are in each group.”

References

Andrews, M. (2021). Doing data science in R: An introduction for Social Scientists. SAGE Publications Ltd.

Tufte, E. R. (2001). The visual display of quantitative information (2nd ed.). Graphics Press.