Mathew K Analytics

Lesson 42 · Data visualisation in python

2 - Case Study Project - Sales and Marketing Dashboard

Welcome! In this lesson, we will build a simple sales and marketing dashboard using Python. You will learn how to load data, explore patterns, and gain…

⬇ 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

Case Study Project: Sales and Marketing Dashboard#

Welcome! In this lesson, we will build a simple sales and marketing dashboard using Python.

You will learn how to load data, explore patterns, and gain meaningful insights.

Perfect for beginners. Let us dive in!

Step 1: Getting Python Ready#

First, let us set up our notebook.

We will import the tools we need, and make sure our notebook is neat.

# Import key libraries
import warnings; warnings.filterwarnings("ignore")
import pandas as pd
import matplotlib.pyplot as plt

# Our dashboard will use pandas for data and matplotlib for charts
# Data setup
url = "https://raw.githubusercontent.com/jbrownlee/Datasets/master/airline-passengers.csv"
df = pd.read_csv(url)
print("Shape:", df.shape)
df.head()
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
# First look at the data
df.info()
print("\nMissing values per column:")
print(df.isnull().sum())
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 144 entries, 0 to 143
Data columns (total 2 columns):
 #   Column      Non-Null Count  Dtype 
---  ------      --------------  ----- 
 0   Month       144 non-null    object
 1   Passengers  144 non-null    int64 
dtypes: int64(1), object(1)
memory usage: 2.4+ KB

Missing values per column:
Month         0
Passengers    0
dtype: int64
# Preview a simple time series plot
plt.figure(figsize=(10,5))
plt.plot(df["Month"], df["Passengers"])
plt.title("Monthly Airline Passengers Over Time")
plt.xlabel("Month")
plt.ylabel("Passengers")
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()
No description has been provided for this image

Step 2: Exploring the Data#

It is vital to look at data from different angles.

Let us explore summary numbers and spot trends.

# Basic summary statistics
df["Passengers"].describe()
count    144.000000
mean     280.298611
std      119.966317
min      104.000000
25%      180.000000
50%      265.500000
75%      360.500000
max      622.000000
Name: Passengers, dtype: float64
# Convert Month to a real date
df["Month"] = pd.to_datetime(df["Month"])
df = df.set_index("Month")
df.head(3)
Passengers
Month
1949-01-01 112
1949-02-01 118
1949-03-01 132
# Drill down: Which months have the highest sales?
top_months = df.sort_values("Passengers", ascending=False).head(5)
print(top_months)
            Passengers
Month                 
1960-07-01         622
1960-08-01         606
1959-08-01         559
1959-07-01         548
1960-06-01         535

Step 3: Avoiding Common Errors#

It is natural to make mistakes.

Let us see how to safely access data and handle errors as you go.

# What if we look for a month that is not there?
try:
    print(df.loc["2050-01"])
except KeyError:
    print("Month not found!")
    
Month not found!
# Let us fill missing data, just in case
df_fixed = df.copy()
df_fixed["Passengers"] = df_fixed["Passengers"].fillna(method="ffill")

Step 4: Making Changes and Updates#

Good dashboards let you update or add to your data easily.

Let us practice adding, editing, and deleting values.

# Editing a passenger total
df_copy = df.copy()
the_month = df_copy.index[0]
df_copy.at[the_month, "Passengers"] = 999
df_copy.head(1)
Passengers
Month
1949-01-01 999
# Add a new summary row for all data
summary = pd.DataFrame({"Passengers": [df_copy["Passengers"].sum()]}, index=["Total"])
df_summary = pd.concat([df_copy, summary])
df_summary.tail()
Passengers
1960-09-01 00:00:00 508
1960-10-01 00:00:00 461
1960-11-01 00:00:00 390
1960-12-01 00:00:00 432
Total 41250
# Remove the last row in the summary table
df_summary = df_summary.iloc[:-1]
df_summary.tail()
Passengers
1960-08-01 00:00:00 606
1960-09-01 00:00:00 508
1960-10-01 00:00:00 461
1960-11-01 00:00:00 390
1960-12-01 00:00:00 432

Step 5: Grouping and Aggregation#

Big datasets have repeating patterns.

Let us find yearly totals and compare across years.

# Find yearly totals
df["Year"] = df.index.year
yearly = df.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
# Quick bar chart - yearly totals
plt.bar(yearly["Year"], yearly["Passengers"])
plt.title("Yearly Total Passengers")
plt.xlabel("Year")
plt.ylabel("Passengers")
plt.show()
No description has been provided for this image

Step 6: Filtering, Sorting, and Mini-Project Preview#

Sometimes you want to look at just part of your data.

Let us select just the busiest months and preview our dashboard.

# Find all months above the average
avg = df["Passengers"].mean()
busy_months = df[df["Passengers"] > avg]
print(f"Busiest months (>{avg:.2f} passengers): {len(busy_months)} found.")
busy_months.head(3)
Busiest months (>280.30 passengers): 64 found.
Passengers Year
Month
1954-07-01 302 1954
1954-08-01 293 1954
1955-06-01 315 1955
# Mini-Project: Simple Sales Dashboard Function
def sales_dashboard(df):
    print("Latest month:", df.index.max().strftime("%b %Y"))
    print("Total passengers:", df["Passengers"].sum())
    print("Mean passengers per month:", int(df["Passengers"].mean()))
    print("Best month:", df["Passengers"].idxmax().strftime("%b %Y"), "with", df["Passengers"].max())

sales_dashboard(df)
Latest month: Dec 1960
Total passengers: 40363
Mean passengers per month: 280
Best month: Jul 1960 with 622
# Mini-Project Part 2: Year-on-Year Growth Calculation
yearly["Growth"] = yearly["Passengers"].pct_change().fillna(0) * 100
for i, row in yearly.iterrows():
    print(f"Year {int(row['Year'])}: {int(row['Passengers'])} passengers, {row['Growth']:.1f}% growth")
    
Year 1949: 1520 passengers, 0.0% growth
Year 1950: 1676 passengers, 10.3% growth
Year 1951: 2042 passengers, 21.8% growth
Year 1952: 2364 passengers, 15.8% growth
Year 1953: 2700 passengers, 14.2% growth
Year 1954: 2867 passengers, 6.2% growth
Year 1955: 3408 passengers, 18.9% growth
Year 1956: 3939 passengers, 15.6% growth
Year 1957: 4421 passengers, 12.2% growth
Year 1958: 4572 passengers, 3.4% growth
Year 1959: 5140 passengers, 12.4% growth
Year 1960: 5714 passengers, 11.2% growth

Step 7: Best Practices, Troubleshooting, and Extra Tips#

You are doing great! Let us wrap up with tips for real-world use.

  • Always check your data for missing or odd values.
  • Save your figures and tables for future use.
  • Automate everything into functions as much as possible.

Next: Challenge exercises for you.

Challenge: Try These Yourself!#

  • Plot only the last 12 months of data.
  • Find the average passengers for each quarter of the year.
  • Build your own prettier bar chart showing the top 3 years.

Experiment, and share your ideas.

Recap#

Let us review what you have learned:

  • How to load, explore, and clean data in Python
  • How to make meaningful charts and dashboards
  • How to find trends and share insights

Keep practicingthis is just the beginning!

Next Steps & Call To Action#

If you enjoyed building this dashboard, give this video a like and subscribe to our channel.

Comment below: What business question would you answer with your own dashboard?

Happy coding!

Found this useful?

All lessons, notebooks and datasets here are free. If they helped you, a coffee keeps new lessons coming.