Aller au contenu principal

Lab 10 — Sales Data Analysis

Hands-on Lab 60 min Advanced

Objectives

  1. Load and clean a sales CSV with Pandas
  2. Compute summary statistics and group-by aggregations
  3. Identify top products and regions
  4. Create 4 charts with Matplotlib

Step 1 — Install Dependencies

mkdir ~/python-course/lab-10 && cd ~/python-course/lab-10
python3 -m venv venv && source venv/bin/activate
pip install pandas numpy matplotlib seaborn

Step 2 — Generate Sample Data

Create generate_data.py:

import pandas as pd
import numpy as np
import random
from datetime import datetime, timedelta

np.random.seed(42)
products = ["Laptop", "Monitor", "Keyboard", "Mouse", "Webcam", "Headset", "Tablet", "Speaker"]
regions = ["North", "South", "East", "West"]
months = pd.date_range("2025-01-01", periods=12, freq="MS")

rows = []
for month in months:
for _ in range(random.randint(30, 50)):
product = random.choice(products)
base_prices = {"Laptop":999,"Monitor":350,"Keyboard":90,"Mouse":30,"Webcam":80,"Headset":150,"Tablet":600,"Speaker":200}
rows.append({
"date": month + timedelta(days=random.randint(0, 28)),
"product": product,
"region": random.choice(regions),
"units": random.randint(1, 20),
"unit_price": base_prices[product] * (1 + np.random.normal(0, 0.05)),
})

df = pd.DataFrame(rows)
df["revenue"] = (df["units"] * df["unit_price"]).round(2)
df.to_csv("sales.csv", index=False)
print(f"Generated {len(df)} records")
python3 generate_data.py

Step 3 — Analyze

Create analysis.py:

import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.ticker as mtick

# Load
df = pd.read_csv("sales.csv", parse_dates=["date"])
df["month"] = df["date"].dt.to_period("M").astype(str)
print(f"Dataset: {df.shape[0]} rows, {df.shape[1]} cols")
print(df.describe())

# ── Analysis ──────────────────────────────────────────────────

# Monthly revenue trend
monthly = df.groupby("month")["revenue"].sum().reset_index()

# Top products
top_products = (df.groupby("product")["revenue"]
.sum()
.sort_values(ascending=False)
.head(5))

# Region performance
region_stats = df.groupby("region").agg(
total_revenue=("revenue", "sum"),
avg_order=("revenue", "mean"),
units_sold=("units", "sum")
).round(2)

print("\nRegion Performance:")
print(region_stats)

# ── Visualizations ────────────────────────────────────────────

fig, axes = plt.subplots(2, 2, figsize=(14, 10))
fig.suptitle("Sales Analysis Dashboard — 2025", fontsize=16, fontweight="bold")

# 1. Monthly Revenue Trend
ax1 = axes[0, 0]
ax1.plot(monthly["month"], monthly["revenue"], marker="o", color="#3776AB", linewidth=2)
ax1.fill_between(range(len(monthly)), monthly["revenue"], alpha=0.2, color="#3776AB")
ax1.set_xticklabels(monthly["month"], rotation=45, ha="right", fontsize=8)
ax1.yaxis.set_major_formatter(mtick.FuncFormatter(lambda x, _: f"${x:,.0f}"))
ax1.set_title("Monthly Revenue Trend")
ax1.set_ylabel("Revenue ($)")
ax1.grid(True, alpha=0.3)

# 2. Top Products
ax2 = axes[0, 1]
bars = ax2.barh(top_products.index, top_products.values,
color=["#FFD43B", "#3776AB", "#28a745", "#dc3545", "#6f42c1"])
ax2.bar_label(bars, fmt="$%.0f", padding=3)
ax2.set_title("Top 5 Products by Revenue")
ax2.set_xlabel("Revenue ($)")

# 3. Revenue by Region (pie)
ax3 = axes[1, 0]
ax3.pie(region_stats["total_revenue"],
labels=region_stats.index,
autopct="%1.1f%%",
colors=["#3776AB", "#FFD43B", "#28a745", "#dc3545"])
ax3.set_title("Revenue by Region")

# 4. Units vs Revenue Scatter
ax4 = axes[1, 1]
product_summary = df.groupby("product").agg(
total_units=("units","sum"),
total_revenue=("revenue","sum")
)
ax4.scatter(product_summary["total_units"], product_summary["total_revenue"],
s=100, c="#3776AB", alpha=0.7, edgecolors="white")
for name, row in product_summary.iterrows():
ax4.annotate(name, (row["total_units"], row["total_revenue"]),
textcoords="offset points", xytext=(5,5), fontsize=8)
ax4.set_title("Units Sold vs Revenue by Product")
ax4.set_xlabel("Total Units Sold")
ax4.set_ylabel("Total Revenue ($)")
ax4.grid(True, alpha=0.3)

plt.tight_layout()
plt.savefig("sales_dashboard.png", dpi=150, bbox_inches="tight")
print("\n✅ Dashboard saved to sales_dashboard.png")
plt.show()
python3 analysis.py

Verification ✅

A sales_dashboard.png file should be created with 4 charts.


Summary

  • pd.read_csv(parse_dates=...) for automatic date parsing
  • df.groupby().agg() for multi-metric aggregation
  • plt.subplots(2, 2) creates a 2×2 dashboard layout
  • ax.bar_label() adds value labels to bar charts
  • plt.savefig(..., dpi=150) for high-resolution output