Week 2: Making the Biomass Case
Building briefing-quality figures with ggplot2
Introduction
You’ve explored the biomass data and learned the ggplot2 syntax. Now you’ll produce briefing-quality figures — the kind you’d include in a policy document to make the case about biomass electricity.
Today’s goals:
- Build a multi-fuel trend chart showing how the UK’s electricity mix has changed
- Compare CO₂ emissions across fuels under different assumptions
- Map where the UK’s wood pellets come from
- Track bioenergy’s share of total electricity over time
- Think about how figure choices affect the story
Exercise 1: The UK electricity mix over time
Build a line chart showing generation from multiple fuels over time. Include at least bioenergy, coal, gas, and wind. This is the “big picture” figure — it shows the transformation of UK electricity over 25 years.
Each fuel gets its own geom_line() layer. Set colour to a string inside aes() to build the legend automatically.
The column names for wind and bioenergy are wind_twh and bioenergy_twh. Add one geom_line() per fuel, each with aes(y = column_name, colour = "Label").
geom_line(aes(y = wind_twh, colour = "Wind",
linetype = "Wind")) +
geom_line(aes(y = bioenergy_twh, colour = "Bioenergy",
linetype = "Bioenergy"))ggplot(elec, aes(x = year)) +
geom_line(aes(y = coal_twh, colour = "Coal",
linetype = "Coal")) +
geom_line(aes(y = gas_twh, colour = "Gas",
linetype = "Gas")) +
geom_line(aes(y = wind_twh, colour = "Wind",
linetype = "Wind")) +
geom_line(aes(y = bioenergy_twh, colour = "Bioenergy",
linetype = "Bioenergy")) +
labs(x = "Year",
y = "Generation (TWh)",
colour = "Fuel", linetype = "Fuel",
title = "UK electricity generation by fuel type",
caption = "Source: DUKES 2025")The big stories: coal’s collapse (from ~120 TWh to ~2 TWh), wind’s rise to become the largest single source (~83 TWh), and gas remaining dominant throughout. Bioenergy’s growth is real but modest compared to wind. Try adding nuclear_twh and solar_twh to complete the picture.
Exercise 2: CO₂ emissions comparison
Different fuels produce very different amounts of CO₂ per unit of electricity. But the answer for biomass depends on what you count. The factors data frame contains emission factors under several accounting scenarios.
Make a bar chart comparing CO₂ per MWh across fuels and scenarios. First, filter to just the “official” scenario for each fuel, then build the bar chart.
The y-axis should be co2_kg_per_mwh. geom_col() makes bars where the height equals the value in the data (unlike geom_bar(), which counts rows).
ggplot(official, aes(x = fuel, y = co2_kg_per_mwh)) +
geom_col() + ...official <- factors[factors$scenario %in%
c("official", "lifecycle"), ]
ggplot(official, aes(x = fuel, y = co2_kg_per_mwh)) +
geom_col() +
labs(x = "Fuel",
y = "CO₂ (kg per MWh)",
title = "Official CO₂ emission factors by fuel",
caption = "Sources: DESNZ, IPCC, UNFCCC")Under official accounting, biomass emits zero CO₂ — the same as wind and solar. Coal emits 910 kg/MWh. This is the figure that makes biomass look carbon-neutral. But is it the whole story? The official figure ignores the CO₂ that comes out of the chimney (~330 kg/MWh) and the supply chain (~60 kg/MWh more). In Week 3, you’ll explore what happens when you change these assumptions.
Exercise 3: Where do the pellets come from?
The UK imports millions of tonnes of wood pellets annually. The imports data frame tracks how much comes from each country.
Make a bar chart showing total import volume by country of origin for 2024. Which country dominates?
Filter with imports[imports$year == 2024, ]. The import volume column is import_kt (kilotonnes).
imports_2024 <- imports[imports$year == 2024, ]
ggplot(imports_2024, aes(x = origin, y = import_kt)) +
geom_col() + ...imports_2024 <- imports[imports$year == 2024, ]
ggplot(imports_2024, aes(x = origin, y = import_kt)) +
geom_col() +
labs(x = "Country of origin",
y = "Imports (thousand tonnes)",
title = "UK wood pellet imports by origin, 2024",
caption = "Source: Forest Research / HMRC")The USA accounts for about 6,900 kt — roughly 74% of all UK pellet imports. Latvia and EU_other are distant runners-up. The dominance of US imports means that transatlantic shipping is a major part of the biomass supply chain. That’s a lot of ocean to cross for something that’s supposedly carbon-neutral.
Extension: Make a misleading figure
This exercise is optional — for students who finish early.
Can you make bioenergy look more important (or less important) than it really is, using only real data and a ggplot2 chart? Some techniques to consider:
- Truncate the y-axis (start it at 30 instead of 0)
- Cherry-pick the date range (only show years where bioenergy grew fastest)
- Use a dual y-axis or unusual scaling
- Choose colours or sizes that emphasise one fuel over another
Make your misleading figure, then write a one-sentence explanation of what’s deceptive about it.
A classic trick: truncate the y-axis to exaggerate a trend. Try ylim() or coord_cartesian() to zoom in on a narrow range.
ggplot(elec, aes(x = year, y = bioenergy_twh)) +
geom_line() +
coord_cartesian(ylim = c(30, 42)) +
labs(title = "Bioenergy generation is surging!")This makes a modest fluctuation look like explosive growth.
Here’s one example — a truncated y-axis that makes recent bioenergy look like explosive growth:
ggplot(elec, aes(x = year, y = bioenergy_twh)) +
geom_line(linewidth = 1.5) +
coord_cartesian(ylim = c(30, 42)) +
labs(x = "Year",
y = "Generation (TWh)",
title = "UK bioenergy generation is surging!") +
theme_minimal()By zooming the y-axis to 30–42, the ~10 TWh variation since 2020 fills the entire plot. A reader glancing at this would think bioenergy has grown dramatically — when it’s actually been roughly flat.
In Week 4, you’ll see these techniques used in the “traitor” briefing. The lesson: every figure involves choices, and those choices shape the story.
Save your work
Copy your best figure code into week2.R in your GitHub repo. Commit and push via GitHub Desktop. Write a commit message that describes what your figures show — not just “week 2 plots”.