A Python script that reads sales data from a CSV, calculates KPIs, and generates a 4-panel dashboard image with monthly trends, top products, region breakdown, and a sales funnel.
Create a realistic CSV dataset with 500 sales records to work with.
import pandas as pd
import numpy as np
np.random.seed(42)
n = 500
products = ['Python Course', 'Web Dev Course', 'AI Bootcamp', 'Arduino Kit', 'Data Science Bundle']
regions = ['North', 'South', 'East', 'West']
months = pd.date_range('2026-01-01', periods=12, freq='MS')
df = pd.DataFrame({
'date': np.random.choice(pd.date_range('2026-01-01', '2026-12-31'), n),
'product': np.random.choice(products, n, p=[0.30, 0.25, 0.20, 0.15, 0.10]),
'region': np.random.choice(regions, n),
'units': np.random.randint(1, 5, n),
'price': np.random.choice([2000, 3500, 8000, 600, 5000], n),
})
df['revenue'] = df['units'] * df['price']
df['month'] = df['date'].dt.to_period('M')
df.to_csv('sales_data.csv', index=False)
print(f"Generated {len(df)} sales records")
print(df.head())
Generated 500 sales records
date product region units price revenue month
0 2026-03-14 Python Course East 2 2000 4000 2026-03
1 2026-07-22 AI Bootcamp North 1 8000 8000 2026-07
...Summarise total revenue, units, top product, and best month.
df = pd.read_csv('sales_data.csv', parse_dates=['date'])
df['month'] = df['date'].dt.to_period('M')
total_revenue = df['revenue'].sum()
total_units = df['units'].sum()
top_product = df.groupby('product')['revenue'].sum().idxmax()
best_month = df.groupby('month')['revenue'].sum().idxmax()
print(f"Total Revenue: ₹{total_revenue:,.0f}")
print(f"Total Units: {total_units:,}")
print(f"Top Product: {top_product}")
print(f"Best Month: {best_month}")
Total Revenue: ₹18,74,200 Total Units: 752 Top Product: Python Course Best Month: 2026-07
One figure with four subplots: monthly revenue trend, top products bar, region pie, and units by product.
import matplotlib.pyplot as plt
import matplotlib.ticker as mticker
fig, axes = plt.subplots(2, 2, figsize=(14, 9))
fig.suptitle('Sales Dashboard — 2026', fontsize=16, fontweight='bold', y=0.98)
fig.patch.set_facecolor('#f8fafc')
COLORS = ['#162447', '#1E3A6E', '#F59C0D', '#e74c3c', '#27ae60']
# ── Panel 1: Monthly Revenue Trend ──
ax1 = axes[0, 0]
monthly = df.groupby('month')['revenue'].sum()
ax1.plot(monthly.index.astype(str), monthly.values, color='#162447', linewidth=2.5, marker='o', markersize=5)
ax1.fill_between(range(len(monthly)), monthly.values, alpha=0.1, color='#162447')
ax1.set_title('Monthly Revenue Trend', fontweight='bold')
ax1.set_ylabel('Revenue (₹)')
ax1.yaxis.set_major_formatter(mticker.FuncFormatter(lambda x, _: f'₹{x/1000:.0f}K'))
ax1.tick_params(axis='x', rotation=45)
ax1.grid(True, alpha=0.3)
ax1.set_facecolor('white')
# ── Panel 2: Top Products ──
ax2 = axes[0, 1]
prod_rev = df.groupby('product')['revenue'].sum().sort_values(ascending=True)
bars = ax2.barh(prod_rev.index, prod_rev.values, color=COLORS)
for bar, val in zip(bars, prod_rev.values):
ax2.text(val + 5000, bar.get_y() + bar.get_height()/2,
f'₹{val/1000:.0f}K', va='center', fontsize=9)
ax2.set_title('Revenue by Product', fontweight='bold')
ax2.xaxis.set_major_formatter(mticker.FuncFormatter(lambda x, _: f'₹{x/1000:.0f}K'))
ax2.set_facecolor('white')
# ── Panel 3: Region Breakdown ──
ax3 = axes[1, 0]
region_rev = df.groupby('region')['revenue'].sum()
wedges, texts, autotexts = ax3.pie(region_rev.values, labels=region_rev.index,
autopct='%1.1f%%', colors=COLORS, startangle=90,
wedgeprops={'edgecolor': 'white', 'linewidth': 2})
ax3.set_title('Revenue by Region', fontweight='bold')
# ── Panel 4: Units Sold by Product ──
ax4 = axes[1, 1]
prod_units = df.groupby('product')['units'].sum().sort_values(ascending=False)
ax4.bar(prod_units.index, prod_units.values, color=COLORS)
ax4.set_title('Units Sold by Product', fontweight='bold')
ax4.set_ylabel('Units')
ax4.tick_params(axis='x', rotation=30)
ax4.set_facecolor('white')
plt.tight_layout()
plt.savefig('sales_dashboard.png', dpi=150, bbox_inches='tight', facecolor='#f8fafc')
plt.show()
print("Dashboard saved as sales_dashboard.png")
Dashboard saved as sales_dashboard.png [4-panel image: line chart, horizontal bar chart, pie chart, vertical bar chart]
You generated a board-ready sales dashboard from raw CSV data in under 40 lines of plotting code. The same 4-panel layout works for any business metric — swap the data source and chart titles.
Spotted a bug, broken code, or something that doesn't look right? Tell us what's off and we'll fix it.