Mathew K Analytics

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…

⬇ Download notebookOpen in Colab ↗

What you'll learn

Data

No separate download needed — the notebook creates or downloads everything it uses.

📓 Full notebook

Download .ipynb

Welcome! 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()
Data shape: (144, 2)
Month Passengers
0 1949-01 112
1 1949-02 118
2 1949-03 132
3 1949-04 129
4 1949-05 121
# 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()
No description has been provided for this image

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()
No description has been provided for this image
# 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()
No description has been provided for this image
# 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.")

    
Are there any missing values? False
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)
    Year  Passengers
0   1949        1520
1   1950        1676
2   1951        2042
3   1952        2364
4   1953        2700
5   1954        2867
6   1955        3408
7   1956        3939
8   1957        4421
9   1958        4572
10  1959        5140
11  1960        5714
# 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()
No description has been provided for this image
# 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()
No description has been provided for this image
# 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()
No description has been provided for this image
# 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()
No description has been provided for this image

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)

    
Whoops! Something went wrong: 'WrongColumn'
# 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)
Awesome! Your chart will use the title: Soaring Skies: A Golden Age of Air Travel

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.