Easier to read with cream paper, a tint, more contrast or larger text? Choose your colours and text, once, for every page.

Free lesson

Making a chart that answers a question

After this lesson: I can make a chart that answers a question.

45 min lesson3 commandsJupyterLab data science lab: pandas, Matplotlib and scikit-learn in the browser

When should the shop hire more staff?

The owner of a bike hire shop wants to take on a summer worker. Which months need the extra help?

The answer is somewhere in 365 rows of numbers. Nobody can see it there. One bar chart shows it at a glance.

By the end of this lesson

Note

I can make a chart that answers a question.

Key words

WordWhat it meansExample
Charta picture of numbers
Bar charta chart that compares groups with bars
Axisthe scale along one side of a chart
Totalall the values added upsum
Meanthe total divided by how many values there are
Dashboardone page of charts that each answer a question

The cells students fill in are left blank in this preview.

Before you start

Note

Press Start the lab. The terminal has no Python of its own, so each Run starts with docker exec jupyter. That runs one command inside the lab's container, which holds hires.csv: one row for every day of 2025.

Start from the question, not the chart

A good chart answers one question. So write the question first.

Then decide two things. Which column splits the days into groups? Which number do you want for each group? "Which weather is busiest?" groups by weather and takes the mean of hires. The Run below does exactly that.

Mean hires for each weather

Command
docker exec jupyter python3 steps/weather.py

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Worked example: from question to chart

QuestionGroup byNumberChart
Which weather is busiest?weathermean hiresBar chart
Which months need more staff?monthmean hiresBar chart, months in order
Are weekends busier?weekend or notmean hiresBar chart with two bars
Do warm days get more hires?no groupsevery dayScatter: temperature across, hires up

The cells students fill in are left blank in this preview.

A total or a mean?

A total adds up every value in a group. A mean divides that total by how many values there are.

Totals mislead when the groups are different sizes. 2025 had 131 sunny days but only 114 cloudy ones, so sunny days win on total partly because there were more of them. Type this cell into a new notebook to see the totals.

Cell: total hires for each weather

Code: python
import pandas as pd

hires = pd.read_csv("hires.csv")
# sum adds up the hires in each group.
totals = hires.groupby("weather")["hires"].sum()
totals

A bar chart must be drawn honestly

Two things make a bar chart lie. The first is the order: pandas sorts month names A to Z, so April comes first. The months Run puts them back in calendar order.

The second is the axis. The axis Run draws the same weather means twice, once with the axis from 0 and once from 220, and compares how the bars look.

Mean hires for each month, in order

Command
docker exec jupyter python3 steps/months.py

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

The same bars on two axes

Command
docker exec jupyter python3 steps/axis.py

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

A common mistake

Warning

Many people think a bar chart's axis may start wherever it looks best. A bar's length is the number, so the axis must start at 0. From 220, sunny looks 12 times as busy as rainy. It is really about 1.4 times as busy.

A dashboard puts answers side by side

A dashboard is one page of a few charts. Each chart answers one question, and each has a title that says which.

This cell draws two bar charts beside each other. Type it under your totals cell and run it. Both axes start at 0, which pandas does for bar charts.

Cell: a two-chart dashboard

Code: python
import matplotlib.pyplot as plt

# Month names in calendar order, not A to Z.
order = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
months = hires.groupby("month")["hires"].mean().reindex(order)
weather = hires.groupby("weather")["hires"].mean()

# One row of two charts, each with a title that is its question.
fig, axes = plt.subplots(1, 2, figsize=(10, 3))
months.plot.bar(ax=axes[0], title="Mean hires a day, by month")
weather.plot.bar(ax=axes[1], title="Mean hires a day, by weather")
plt.tight_layout()

Going further: how busy is a usual day?

A histogram counts how many days fall into each band of hires, such as 250 to 299.

Type docker exec jupyter python3 steps/hist.py into the terminal and press Enter. Which band has the most days? Add a third chart to your dashboard that shows it.

About this lab and its source: JupyterLab data science lab: pandas, Matplotlib and scikit-learn in the browser

Teaching a class? Set this module for your students with a teacher guide, marked assignments and a lab for every student.