Free tutorials & notes in Hindi & English · Clean code examples 🧰 Free PDF & Image Tools →
📊 Week 4 – Visualisation & Storytelling  ·  Day 24

Day 24: Data Storytelling & Dashboards

⏱ 2 hours📶 Intermediate🎯 100% self-study
Day 24 / 60

✅ Today you will learn

  • Story structure: context → insight → action
  • Know your audience: CEO vs manager vs analyst
  • Chart makeover: declutter and highlight
  • KPI cards and a one-page dashboard
  • Write headlines that state the finding

🏢 In the real world

Two analysts find the same thing: monthly-contract customers churn 5× more. One sends a 20-chart notebook; nobody reads it. The other sends one slide: “Monthly plans lose 44% of customers – a ₹100 discount for the 600 riskiest customers could add about ₹7 lakh a year.” Guess who gets promoted. Storytelling is the last mile of data science.

The story structure

Context: what we looked at and whyInsight: the one surprising finding (with a number)Impact: what it costs or earnsAction: what to do, by whom, by when
Every data story in four parts
AudienceWantsGive them
CEODecision in 1 minuteOne headline, 3 KPIs, 1 recommendation
ManagerWhat to change in their team3–4 charts with drill-down by region/product
Analyst / techHow you did itMethod, assumptions, notebook link

Chart makeover: before and after

Python
import pandas as pd
import matplotlib.pyplot as plt
t = pd.read_csv("telecom_churn.csv")
r = (t.groupby("contract")["churn"].apply(lambda c: (c == "Yes").mean()) * 100).round(1)
fig, ax = plt.subplots(1, 2, figsize=(12, 4.2))
# BEFORE: default pie, no message
ax[0].pie(r, labels=r.index, autopct="%1.1f%%", shadow=True, explode=[0.05] * 3)
ax[0].set_title("Churn by contract")
# AFTER: sorted bars, one highlight, insight title, direct labels
r = r.sort_values()
colors = ["#cbd5e1", "#cbd5e1", "#dc2626"]
bars = ax[1].barh(r.index, r.values, color=colors)
ax[1].bar_label(bars, labels=[f"{v:.0f}%" for v in r.values], padding=4, fontsize=11, fontweight="bold")
ax[1].set_title("Monthly-plan customers churn ~5× more than two-year customers", loc="left", fontsize=11)
ax[1].spines[["top", "right", "bottom"]].set_visible(False); ax[1].set_xticks([])
plt.tight_layout(); plt.show()
Before: a confusing pie chart. After: a sorted bar chart with the monthly contract highlighted in red
Left: a pie of rates (wrong chart – rates do not add up to a whole). Right: the message in 3 seconds.
⚠️ Common storytelling mistakes

Pie charts of rates; 3D effects; rainbow colours; titles like “Chart 3”; too many decimals (29.137%); showing every chart you made instead of the three that matter.

Put a rupee value on the insight

Python
import pandas as pd
t = pd.read_csv("telecom_churn.csv")
monthly = t[t["contract"] == "Monthly"]
churners = (monthly["churn"] == "Yes").sum()
avg_bill = monthly["monthly_charges"].mean()
lost_per_year = churners * avg_bill * 12
print(f"Monthly-plan churners: {churners} | avg bill ₹{avg_bill:.0f}")
print(f"Revenue lost per year ≈ ₹{lost_per_year / 1e5:.1f} lakh")
saved = 0.25 * churners                  # assumption: the offer keeps 1 in 4 churners
gain = saved * avg_bill * 12
cost_all = len(monthly) * 100 * 12       # ₹100/month off for EVERY monthly customer
cost_target = 600 * 100 * 12             # only the 600 highest-risk customers (model, Day 58)
print(f"Revenue kept if 25% are saved: ₹{gain / 1e5:.1f} lakh")
print(f"Offer to everyone:  cost ₹{cost_all / 1e5:.1f} lakh → net ₹{(gain - cost_all) / 1e5:+.1f} lakh")
print(f"Offer to top 600:   cost ₹{cost_target / 1e5:.1f} lakh → net ₹{(gain - cost_target) / 1e5:+.1f} lakh")
Monthly-plan churners: 721 | avg bill ₹676 Revenue lost per year ≈ ₹58.5 lakh Revenue kept if 25% are saved: ₹14.6 lakh Offer to everyone: cost ₹19.7 lakh → net ₹-5.1 lakh Offer to top 600: cost ₹7.2 lakh → net ₹+7.4 lakh
🧠 State your assumptions

Notice the twist: a discount for everyone loses money, a targeted one earns it. The 25% save-rate is an assumption, so say so on the slide and propose a small test first (Day 31). Honest numbers build trust.

A one-page dashboard

Python
import pandas as pd
import matplotlib.pyplot as plt
t = pd.read_csv("telecom_churn.csv")
t["churned"] = t["churn"] == "Yes"
fig = plt.figure(figsize=(12, 7.2))
gs = fig.add_gridspec(3, 4, height_ratios=[0.55, 1, 1], hspace=0.55, wspace=0.35)
kpis = [("Customers", f"{len(t):,}"), ("Churn rate", f"{t['churned'].mean() * 100:.1f}%"),
        ("Avg bill", f"₹{t['monthly_charges'].mean():.0f}"), ("Complaints/cust", f"{t['complaints'].mean():.2f}")]
for i, (name, val) in enumerate(kpis):
    a = fig.add_subplot(gs[0, i]); a.axis("off")
    a.add_patch(plt.Rectangle((0, 0), 1, 1, color="#eef2ff", transform=a.transAxes))
    a.text(0.5, 0.62, val, ha="center", fontsize=20, fontweight="bold", color="#3730a3")
    a.text(0.5, 0.22, name, ha="center", fontsize=10, color="#475569")
a1 = fig.add_subplot(gs[1:, :2])
r = t.groupby("contract")["churned"].mean().sort_values() * 100
a1.barh(r.index, r, color=["#cbd5e1", "#cbd5e1", "#dc2626"]); a1.set_title("Churn % by contract", loc="left")
a2 = fig.add_subplot(gs[1, 2:])
tg = pd.cut(t["tenure_months"], [0, 6, 12, 24, 48, 72], labels=["0-6", "7-12", "13-24", "25-48", "49-72"])
(t.groupby(tg, observed=True)["churned"].mean() * 100).plot(ax=a2, marker="o", color="#4f46e5"); a2.set_title("Churn % falls with tenure", loc="left"); a2.set_xlabel("")
a3 = fig.add_subplot(gs[2, 2:])
cp = t["complaints"].clip(upper=4).map(lambda c: "4+" if c == 4 else str(c))     # group rare 4,5,6… together
(t.groupby(cp)["churned"].mean() * 100).plot(kind="bar", ax=a3, color="#f59e0b", rot=0); a3.set_title("Each complaint raises churn", loc="left"); a3.set_xlabel("complaints")
fig.suptitle("TeleOne churn dashboard – act on new, monthly, complaining customers", fontsize=14, fontweight="bold", x=0.02, ha="left")
plt.show()
One-page churn dashboard with KPI cards, churn by contract, by tenure and by complaints
KPI row on top, the biggest driver large on the left, supporting evidence on the right.

Headlines that work

Weak (topic)

  • Churn by contract
  • Monthly revenue 2024
  • Ratings analysis

Strong (finding)

  • Monthly plans churn 5× more
  • Oct–Nov earned 27% of 2024 revenue
  • Power banks get the most 1–3 star ratings
💼 The one-slide test

If you had one slide and one minute with the CEO, what would it say? Write that first – then build only the charts that support it.

🏅 Job skills unlocked today

✔ Structure a data story✔ Redesign a cluttered chart✔ Quantify impact in rupees✔ Build a one-page KPI dashboard

Practice tasks

🏋️ Practice – do it yourself

Task 1: Rewrite these titles as findings: “Sales by city”, “Students by tuition”, “AQI 2024”.
Task 2: Make a before/after makeover of a pie chart of revenue by category from the sales data.
Show solution
Python
import pandas as pd, matplotlib.pyplot as plt
s = pd.read_csv("sales_data.csv")
s["revenue"] = s["quantity"] * s["unit_price"] * (1 - s["discount"])
c = (s.groupby("category")["revenue"].sum() / s["revenue"].sum() * 100).sort_values()
fig, ax = plt.subplots(figsize=(7, 3.2))
b = ax.barh(c.index, c, color=["#cbd5e1"] * 4 + ["#4f46e5"])
ax.bar_label(b, labels=[f"{v:.0f}%" for v in c], padding=3)
ax.set_title("Electronics alone brings over half of revenue", loc="left"); ax.set_xticks([])
ax.spines[["top", "right", "bottom"]].set_visible(False); plt.show()
Revenue share by category, Electronics highlighted
Output of the program
Task 3: Write a 4-line story (context, insight, impact, action) for the festive-season finding from Day 19.

Quick quiz

🧠 Quick Quiz – test yourself

1. The best chart title…
Readers remember conclusions, not topics.
2. Why is a pie chart of churn rates wrong?
Pies are only for parts of one total.
3. For a CEO, the dashboard should start with…
Details go lower or in an appendix.
4. Using grey for most bars and one strong colour…
Pre-attentive highlighting.
5. An impact estimate based on an assumed save-rate should…
Transparency builds trust.

Interview corner

💼 Interview Corner

How do you present findings to a non-technical audience?

Lead with the answer, not the method: one headline with a number, the business impact in rupees, a recommended action, and two or three clean charts. Keep technical details in an appendix and avoid jargon like p-values unless asked.

What makes a good dashboard?

A clear purpose and audience, KPIs at the top, the most important chart largest and top-left, consistent colours, filters only where needed, and it loads fast. Fewer charts, each answering a question.

Summary

  • Context → insight → impact → action.
  • Declutter, sort, highlight one thing, write finding titles.
  • Put a rupee value on insights and state assumptions.
  • Dashboard: KPI row, key chart large, supporting charts small.
➡️ Next

Day 25: Mini project – student performance analysis with a complete visual report.

Frequently Asked Questions

Should I build dashboards in Python or Power BI?
Learn both. Python for analysis and custom charts; Power BI/Tableau for business dashboards that managers refresh themselves (Day 52).
Any book to read?
“Storytelling with Data” by Cole Nussbaumer Knaflic is the classic and very practical.
← Data Science (60 Days)
🔗

Share this topic with a friend

यह topic किसी दोस्त को भेजें

Found it useful? Send it to a classmate learning the same thing.

अच्छा लगा? जो दोस्त यही सीख रहा है, उसे भेज दीजिए।

Next topicDay 25: Mini Project: Student Performance Your progress: 24 / 60 (40%) · Lesson 25 / 60 Continue →

How was this lesson?

Your feedback helps us make the content better.

Write a review or suggestion (optional)

After approval, your name and city may appear publicly with your review. Please do not write your email or phone number.

▶ CodingEasily on YouTube

Learn with video lessons in easy Hindi

Featured video: RDBMS Part 3 – Class XI Commerce IT

▶ Subscribe – it’s free