Lesson 23 · Data visualisation in python
Best Practices for Data Storytelling Using Visuals in Bible Teaching | Week 07–08
In this lesson, you will learn how to turn data into clear stories using simple yet powerful graphics. You do not need any background we will build step by…
- CourseData visualisation in python
- Lesson23 of 34
- Video12 min
- FormatJupyter notebook · 14 code cells
What you'll learn
Data
No separate download needed — the notebook creates or downloads everything it uses.
📓 Full notebook
Download .ipynbWelcome! Data Storytelling with Visuals in Python#
In this lesson, you will learn how to turn data into clear stories using simple yet powerful graphics.
You do not need any background we will build step by step.
By the end, you will visualize a real dataset like a pro storyteller!
# First, suppress warnings to keep things tidy
import warnings
warnings.filterwarnings("ignore")
# Now, let us import the basic libraries you will use
import pandas as pd
import matplotlib.pyplot as plt
What is data storytelling?#
Turning raw data into pictures helps people understand patterns, trends, and surprises.
A clear visual can make even tricky ideas much easier to see.
# Data setup: Let us fetch a real dataset of monthly airline passengers
url = "https://raw.githubusercontent.com/jbrownlee/Datasets/master/airline-passengers.csv"
data = pd.read_csv(url)
print("Data shape:", data.shape)
data.head()
# Quick preview: Plotting the time series
plt.figure(figsize=(10,5))
plt.plot(data["Month"], data["Passengers"], marker="o")
plt.title("Monthly Airline Passengers (1949-1960)")
plt.xlabel("Month")
plt.ylabel("Number of Passengers")
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()
Crafting a clear visual: A few golden rules#
- Keep the axis labels short but meaningful.
- Titles should say exactly what you are showing.
- Avoid clutterless is more!
- Use color or extra markers only to help tell the story.
# Highlighting trends can help your viewers
plt.figure(figsize=(10,5))
plt.plot(data["Month"], data["Passengers"], color="skyblue", linewidth=2, label="Passengers")
plt.title("How airline passengers increased over time")
plt.xlabel("Month")
plt.ylabel("Passengers")
plt.legend()
plt.grid(True, linestyle=":", alpha=0.5)
plt.xticks(data["Month"][::12], rotation=45)
plt.tight_layout()
plt.show()
# Annotating visuals makes stories pop!
plt.figure(figsize=(10,5))
plt.plot(data["Month"], data["Passengers"], color="mediumseagreen", linewidth=2)
plt.title("Biggest jump in airline passengers")
plt.xlabel("Month")
plt.ylabel("Passengers")
max_month = data.iloc[data["Passengers"].idxmax()]["Month"]
max_passengers = data["Passengers"].max()
plt.annotate(
"Peak: {}".format(max_passengers),
xy=(max_month, max_passengers),
xytext=(max_month, max_passengers+60),
arrowprops=dict(facecolor="red", shrink=0.05),
color="red"
)
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()
# Catching common pitfalls: Missing or wrong data
print("Are there any missing values?", data.isnull().values.any())
if data.isnull().values.any():
print("Let us see where:")
print(data.isnull().sum())
else:
print("All good! No missing values to worry about.")
# Creating new insights: Calculate yearly totals
data["Year"] = data["Month"].str[:4]
yearly = data.groupby("Year")["Passengers"].sum().reset_index()
print(yearly)
# Visualizing yearly growth with a bar chart
plt.figure(figsize=(8,5))
plt.bar(yearly["Year"], yearly["Passengers"], color="coral")
plt.title("Yearly Airline Passengers")
plt.xlabel("Year")
plt.ylabel("Total Passengers")
plt.tight_layout()
plt.show()
# Making comparisons: Highlighting changes
plt.figure(figsize=(8,5))
bars = plt.bar(yearly["Year"], yearly["Passengers"], color="lightgrey")
bars[-1].set_color("red")
plt.title("Which year had the most passengers?")
plt.xlabel("Year")
plt.ylabel("Passengers")
plt.tight_layout()
plt.show()
# Filtering the data: Focus on recent years
recent = data[data["Year"].astype(int) >= 1955]
plt.figure(figsize=(8,5))
plt.plot(recent["Month"], recent["Passengers"], marker="o", color="navy")
plt.title("Passengers from 1955 onward")
plt.xlabel("Month")
plt.ylabel("Passengers")
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()
# Combining data: Add a moving average for smooth trends
data["MA_12"] = data["Passengers"].rolling(window=12).mean()
plt.figure(figsize=(10,5))
plt.plot(data["Month"], data["Passengers"], label="Monthly", color="lightgrey")
plt.plot(data["Month"], data["MA_12"], label="12-month Avg", color="blue", linewidth=2)
plt.title("Monthly vs. Smoothed Trend (12-month average)")
plt.xlabel("Month")
plt.ylabel("Passengers")
plt.legend()
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()
Mini challenge: Pause and make your own chart!#
Try making a chart that tells a story about a time when passenger numbers droppedwhat could have caused it?
Use titles, colors, or labels to help your audience see the drop.
Remember: a strong data story answers questions your viewers care about.
# Troubleshooting: Handling broken charts
try:
plt.plot(data["WrongColumn"])
except Exception as e:
print("Whoops! Something went wrong:", e)
# Quick tip: Ask for help with input()
question = input("What title would you like for your next chart? ")
print("Awesome! Your chart will use the title:", question)
Recap#
- You learned how to read, check, and fix data.
- You made visuals that show both details and big-picture trends.
- You found ways to highlight changes and tell stronger stories.
With these skills, you can turn numbers into insights anyone can follow!
Want to level up your Python data skills?#
Try these challenges:
- Make a double-line chart comparing two years side by side.
- Change the color scheme and style for a bolder visual.
- Write a 1-sentence headline for your favorite chart.
If you enjoyed this, like and subscribe for more beginner tutorials and mini projects!
Found this useful?
All lessons, notebooks and datasets here are free. If they helped you, a coffee keeps new lessons coming.



