Lý thuyết
Bài 13/17

Data Storytelling

Kỹ năng truyền tải insights thông qua narrative và visualization

Data Storytelling

Data Storytelling and Visualization

1. Introduction

Tại sao Data Storytelling quan trọng?

Data không tự nói lên được điều gì. Data Storytelling chuyển đổi numbers thành narrative có impact, giúp stakeholders hiểu, tin tưởng, và hành động dựa trên insights của bạn.

1.1 The Data Storytelling Framework

Text
1┌─────────────────────────────────────────────────────────┐
2│ Data Storytelling = 3 Pillars │
3├─────────────────────────────────────────────────────────┤
4│ │
5│ ┌──────────────┐ │
6│ │ DATA │ │
7│ │ Analysis │ │
8│ │ Accuracy │ │
9│ │ Context │ │
10│ └──────┬───────┘ │
11│ │ │
12│ v │
13│ ┌──────────────┐ ┌──────────────┐ │
14│ │ VISUALS │──────│ NARRATIVE │ │
15│ │ Charts │ │ Story Arc │ │
16│ │ Design │ │ Insights │ │
17│ │ Clarity │ │ Recommend │ │
18│ └──────────────┘ └──────────────┘ │
19│ │
20│ ═══════════════════════════ │
21│ STORY IMPACT │
22│ Decision + Action │
23│ │
24└─────────────────────────────────────────────────────────┘

2. Know Your Audience

2.1 Audience Segmentation

Text
1┌─────────────────────────────────────────────────────────┐
2│ Audience Types │
3├─────────────────────────────────────────────────────────┤
4│ │
5│ 👔 EXECUTIVES │
6│ • Want: Bottom line impact, strategic insights │
7│ • Time: 2-5 minutes │
8│ • Format: High-level summary, key metrics │
9│ • Question: "So what?" and "What should we do?" │
10│ │
11│ 📊 ANALYSTS / DATA TEAM │
12│ • Want: Methodology, details, validation │
13│ • Time: 15-30 minutes │
14│ • Format: Technical depth, assumptions │
15│ • Question: "How did you get this?" "Is it correct?" │
16│ │
17│ 🎯 OPERATIONS / MANAGERS │
18│ • Want: Actionable steps, team impact │
19│ • Time: 5-10 minutes │
20│ • Format: Specific recommendations, next steps │
21│ • Question: "What do we need to change?" │
22│ │
23│ 🌐 GENERAL STAKEHOLDERS │
24│ • Want: Context, simple explanations │
25│ • Time: 5-10 minutes │
26│ • Format: Visuals, analogies, minimal jargon │
27│ • Question: "Why does this matter to me?" │
28│ │
29└─────────────────────────────────────────────────────────┘

2.2 Tailoring Your Message

Python
1# Example: Same data, different presentations
2
3# Revenue increased 15% YoY
4
5# For Executives
6"""
7Executive Summary:
8Revenue grew 15% ($2.3M) year-over-year, exceeding target by 3%.
9Key driver: New product line contributed 40% of growth.
10Recommendation: Increase marketing budget by $500K for Q2.
11"""
12
13# For Operations Team
14"""
15Q1 Performance:
16- Total revenue: $17.6M (+15% YoY)
17- Average order value: $127 (+8%)
18- Order volume: 138,500 (+6.5%)
19
20Action items:
211. Scale fulfillment capacity by 10%
222. Prioritize inventory for Product Line X
233. Extend support hours for peak periods
24"""
25
26# For Data Team
27"""
28Analysis Details:
29- Period: Q1 2024 vs Q1 2023
30- Data source: Sales_Master, cleaned for returns
31- Methodology: Standard YoY comparison, seasonally adjusted
32- Confidence: 95% CI [14.2%, 15.8%]
33- Caveats: Excludes one-time enterprise deal ($400K)
34"""

3. Story Structure

3.1 The SCQA Framework

Text
1┌─────────────────────────────────────────────────────────┐
2│ SCQA Framework │
3├─────────────────────────────────────────────────────────┤
4│ │
5│ S - SITUATION (Context) │
6│ "Currently, our customer churn rate is 8%..." │
7│ │
8│ C - COMPLICATION (Problem) │
9│ "...but this has increased 40% in the last │
10│ quarter, threatening annual revenue by $2M." │
11│ │
12│ Q - QUESTION (What we need to solve) │
13│ "What's driving this increase and how can │
14│ we reduce churn back to historical levels?" │
15│ │
16│ A - ANSWER (Your insight + recommendation) │
17│ "Analysis shows 60% of churners cite pricing │
18│ as primary reason. Introducing a loyalty tier │
19│ could reduce churn by 25%, saving $500K." │
20│ │
21└─────────────────────────────────────────────────────────┘

3.2 The Pyramid Principle

Text
1┌─────────────────┐
2 │ Key Message │ ← Start here!
3 │ (So what?) │
4 └────────┬────────┘
5
6 ┌────────────────────┼────────────────────┐
7 v v v
8 ┌─────────┐ ┌─────────┐ ┌─────────┐
9 │Support 1│ │Support 2│ │Support 3│
10 │ Point │ │ Point │ │ Point │
11 └────┬────┘ └────┬────┘ └────┬────┘
12 │ │ │
13 ┌────┴────┐ ┌────┴────┐ ┌────┴────┐
14 │ Data │ │ Data │ │ Data │
15 │Evidence │ │Evidence │ │Evidence │
16 └─────────┘ └─────────┘ └─────────┘
17
18Example:
19Key Message: "We should expand to Region X"
20├── Support 1: Market size is $50M with 15% growth
21│ └── Data: Market research, competitor analysis
22├── Support 2: Customer demand exists (survey results)
23│ └── Data: Survey: 72% interested, 45% willing to pay premium
24└── Support 3: ROI positive within 18 months
25 └── Data: Financial projections, sensitivity analysis

3.3 Three-Act Structure

Python
1# Act 1: Setup (Where are we?)
2"""
3Context: Our e-commerce platform serves 500K active customers.
4 Average order value is $85 with 2.3 orders per customer/year.
5 We've been growing 20% annually for 3 years.
6"""
7
8# Act 2: Conflict (What's the problem?)
9"""
10Challenge: Q4 data shows concerning trends:
11- Cart abandonment increased from 68% to 76%
12- Mobile conversion dropped 15%
13- Customer complaints about checkout up 200%
14
15Root cause: Analysis reveals checkout flow has 7 steps
16vs. industry standard of 3-4 steps.
17"""
18
19# Act 3: Resolution (What should we do?)
20"""
21Solution: Redesign checkout to 4 steps
22Expected impact:
23- Reduce abandonment by 10 percentage points
24- Recover $2.5M in annual revenue
25- Timeline: 6 weeks development, 2 weeks testing
26
27Next steps: Approve budget, assign team, begin A/B test design
28"""

4. Visualization Best Practices

4.1 Chart Selection Guide

Text
1┌──────────────────────────────────────────────────────────┐
2│ Chart Selection Matrix │
3├──────────────────────────────────────────────────────────┤
4│ │
5│ COMPARISON │
6│ ├── Between categories → Bar Chart │
7│ ├── Over time → Line Chart │
8│ └── Multiple groups → Grouped/Stacked Bar │
9│ │
10│ COMPOSITION │
11│ ├── Parts of whole (static) → Pie, Donut │
12│ ├── Parts over time → Stacked Area │
13│ └── Hierarchical → Treemap │
14│ │
15│ DISTRIBUTION │
16│ ├── Single variable → Histogram, Box Plot │
17│ ├── Two variables → Scatter Plot │
18│ └── Many variables → Heatmap │
19│ │
20│ RELATIONSHIP │
21│ ├── Two variables → Scatter Plot │
22│ ├── Correlation matrix → Heatmap │
23│ └── Network → Graph/Network Diagram │
24│ │
25│ TREND │
26│ ├── Single series → Line Chart │
27│ ├── Multiple series → Multi-line │
28│ └── With target → Line + Reference Line │
29│ │
30└──────────────────────────────────────────────────────────┘

4.2 Before and After Examples

Python
1import matplotlib.pyplot as plt
2import pandas as pd
3import numpy as np
4
5# Sample data
6categories = ['Product A', 'Product B', 'Product C', 'Product D', 'Product E']
7values = [23, 45, 12, 38, 29]
8
9# BAD: 3D Pie Chart (cluttered, hard to compare)
10fig, axes = plt.subplots(1, 2, figsize=(14, 5))
11
12# Don't use pie for comparisons
13axes[0].pie(values, labels=categories, autopct='%1.1f%%')
14axes[0].set_title('❌ BAD: Pie Chart for Comparison')
15
16# GOOD: Horizontal Bar Chart (easy to compare)
17sorted_idx = np.argsort(values)[::-1]
18sorted_cats = [categories[i] for i in sorted_idx]
19sorted_vals = [values[i] for i in sorted_idx]
20
21bars = axes[1].barh(sorted_cats, sorted_vals, color='steelblue')
22axes[1].set_xlabel('Sales ($K)')
23axes[1].set_title('✅ GOOD: Sorted Bar Chart')
24axes[1].bar_label(bars, fmt='$%dK')
25axes[1].invert_yaxis()
26
27plt.tight_layout()
28plt.show()

4.3 Focus Attention

Python
1# Highlight key data points
2fig, axes = plt.subplots(1, 2, figsize=(14, 5))
3
4months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun']
5sales = [120, 135, 128, 142, 138, 165]
6target = 150
7
8# BAD: All same color, no focus
9axes[0].plot(months, sales, 'o-', linewidth=2)
10axes[0].axhline(target, linestyle='--', label='Target')
11axes[0].set_title('❌ BAD: No Visual Hierarchy')
12axes[0].legend()
13
14# GOOD: Highlight the insight
15colors = ['gray' if v < target else 'green' for v in sales]
16axes[1].bar(months, sales, color=colors)
17axes[1].axhline(target, color='red', linestyle='--', label='Target: $150K')
18
19# Annotate the success
20axes[1].annotate('Hit target! ↑12%',
21 xy=(5, 165),
22 xytext=(4, 175),
23 fontsize=11,
24 fontweight='bold',
25 color='green',
26 arrowprops=dict(arrowstyle='->', color='green'))
27
28axes[1].set_ylabel('Sales ($K)')
29axes[1].set_title('✅ GOOD: Highlight Key Insight')
30axes[1].legend()
31
32plt.tight_layout()
33plt.show()

5. Writing Insights

5.1 The Insight Formula

Text
1INSIGHT = OBSERVATION + IMPLICATION + ACTION
2
3Example:
4❌ Weak: "Sales increased 15% in Q4."
5
6✅ Strong: "Sales increased 15% in Q4, driven primarily by
7 the holiday promotion (contributing 60% of growth).
8 To sustain this momentum, we should extend the
9 promotion into Q1 with a 'New Year' theme."

5.2 Headline Hierarchy

Text
1Level 1: KEY FINDING (Lead with the insight)
2└── Level 2: Supporting Evidence
3 └── Level 3: Details/Data
4
5Example Structure:
6
7===========================================
8CUSTOMER CHURN IS COSTING US $2M ANNUALLY
9===========================================
10
11Churn rate jumped 40% in Q4
12├── 8.2% vs 5.9% same period last year
13├── 2,400 customers lost (vs 1,700)
14└── Average customer value: $850
15
16Top 3 reasons for churn (exit survey):
171. Pricing (38%) - Competitors undercutting
182. Service (28%) - Support response time
193. Features (19%) - Missing key functionality
20
21Recommended action: Loyalty program launch
22├── Expected reduction: 25% of at-risk churners
23├── Investment: $150K
24└── ROI: 10x within 12 months

5.3 Avoiding Common Pitfalls

Python
1# ❌ DON'T: Use jargon
2bad = """
3The YoY delta in the LTV:CAC ratio indicates a deteriorating
4unit economics profile with ARPU declining 15% while CPA
5increased 23%, resulting in suboptimal ROAS.
6"""
7
8# ✅ DO: Use plain language
9good = """
10We're spending more to acquire customers who are worth less:
11- Cost to acquire a customer: up 23%
12- Revenue per customer: down 15%
13- Result: We lose money until month 8 (vs month 5 last year)
14
15Bottom line: Each new customer now takes 3 months longer
16to become profitable.
17"""
18
19# ❌ DON'T: Bury the lead
20bad_order = """
211. Methodology explanation (2 paragraphs)
222. Data collection process
233. Analysis approach
244. Findings summary
255. Recommendation (finally!)
26"""
27
28# ✅ DO: Lead with the conclusion
29good_order = """
301. Key recommendation and expected impact
312. Main finding supporting the recommendation
323. Evidence and data
334. Methodology notes (appendix or available on request)
34"""

6. Building Presentations

6.1 Slide Structure

Text
1┌─────────────────────────────────────────────────────────┐
2│ Effective Slide Layout │
3├─────────────────────────────────────────────────────────┤
4│ │
5│ ┌─────────────────────────────────────────────────┐ │
6│ │ HEADLINE: States the insight (not just topic) │ │
7│ │ ❌ "Q4 Sales Performance" │ │
8│ │ ✅ "Q4 Sales Beat Target by 15%" │ │
9│ └─────────────────────────────────────────────────┘ │
10│ │
11│ ┌──────────────────────┬──────────────────────────┐ │
12│ │ │ │ │
13│ │ VISUAL │ KEY TAKEAWAYS │ │
14│ │ (Chart) │ • Point 1 │ │
15│ │ │ • Point 2 │ │
16│ │ │ • Point 3 │ │
17│ │ │ │ │
18│ └──────────────────────┴──────────────────────────┘ │
19│ │
20│ ┌─────────────────────────────────────────────────┐ │
21│ │ Source: Sales_Master database, Dec 2024 │ │
22│ └─────────────────────────────────────────────────┘ │
23│ │
24└─────────────────────────────────────────────────────────┘

6.2 Presentation Flow

Text
1PRESENTATION TEMPLATE: Analysis Findings
2
31. EXECUTIVE SUMMARY (1 slide)
4 - Key finding
5 - Business impact ($)
6 - Recommendation
7
82. CONTEXT (1-2 slides)
9 - Business question we answered
10 - Why it matters now
11
123. KEY FINDINGS (3-5 slides)
13 - Finding 1 + evidence
14 - Finding 2 + evidence
15 - Finding 3 + evidence
16
174. DEEP DIVE (optional, 2-3 slides)
18 - Detailed analysis
19 - Methodology notes
20 - Supporting data
21
225. RECOMMENDATIONS (1-2 slides)
23 - Specific actions
24 - Expected outcomes
25 - Timeline and owners
26
276. APPENDIX
28 - Detailed tables
29 - Methodology
30 - Additional charts

7. Interactive Storytelling

7.1 Dashboard Narrative

Python
1import plotly.express as px
2import plotly.graph_objects as go
3from plotly.subplots import make_subplots
4
5# Create narrative dashboard
6fig = make_subplots(
7 rows=2, cols=2,
8 subplot_titles=(
9 '📈 Revenue Trend: Exceeding Targets',
10 '🎯 Customer Segments: Focus on Premium',
11 '📊 Regional Performance',
12 '💡 Key Metrics Summary'
13 ),
14 specs=[[{"type": "scatter"}, {"type": "pie"}],
15 [{"type": "bar"}, {"type": "table"}]]
16)
17
18# Data
19months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun']
20revenue = [1.2, 1.4, 1.3, 1.5, 1.6, 1.8]
21target = [1.3, 1.3, 1.3, 1.4, 1.4, 1.5]
22
23# Chart 1: Revenue trend with annotation
24fig.add_trace(
25 go.Scatter(x=months, y=revenue, name='Actual', line=dict(width=3, color='green')),
26 row=1, col=1
27)
28fig.add_trace(
29 go.Scatter(x=months, y=target, name='Target', line=dict(dash='dash', color='gray')),
30 row=1, col=1
31)
32
33# Chart 2: Customer segments
34fig.add_trace(
35 go.Pie(labels=['Premium', 'Standard', 'Basic'],
36 values=[45, 35, 20],
37 marker_colors=['gold', 'steelblue', 'lightgray']),
38 row=1, col=2
39)
40
41# Chart 3: Regional
42regions = ['North', 'South', 'East', 'West']
43performance = [120, 95, 110, 85]
44colors = ['green' if p >= 100 else 'red' for p in performance]
45fig.add_trace(
46 go.Bar(x=regions, y=performance, marker_color=colors, name='vs Target %'),
47 row=2, col=1
48)
49
50# Chart 4: Summary table
51fig.add_trace(
52 go.Table(
53 header=dict(values=['Metric', 'Value', 'Status']),
54 cells=dict(values=[
55 ['Revenue', 'Growth', 'NPS'],
56 ['$8.8M', '+23%', '72'],
57 ['✅ On Track', '✅ Above Target', '⚠️ Monitor']
58 ])
59 ),
60 row=2, col=2
61)
62
63fig.update_layout(
64 title_text="Q2 Business Review: Strong Performance with Growth Opportunities",
65 title_font_size=16,
66 showlegend=False,
67 height=600
68)
69
70# Add annotation highlighting key insight
71fig.add_annotation(
72 x='Jun', y=1.8,
73 text="Record month!<br>+20% vs target",
74 showarrow=True,
75 arrowhead=2,
76 row=1, col=1
77)
78
79fig.show()

7.2 Scroll-based Narrative

Python
1# Structure for scrollytelling (conceptual)
2narrative_sections = [
3 {
4 'headline': 'Customer behavior is changing',
5 'visual': 'time_series_chart',
6 'text': 'Over the past year, mobile purchases have grown 45% while desktop declined 12%.',
7 'data_highlight': 'mobile_growth'
8 },
9 {
10 'headline': 'Mobile users convert differently',
11 'visual': 'funnel_comparison',
12 'text': 'Mobile users browse 3x more products but convert 40% less. Cart abandonment is the key blocker.',
13 'data_highlight': 'cart_abandonment'
14 },
15 {
16 'headline': 'The $3M opportunity',
17 'visual': 'impact_calculator',
18 'text': 'Improving mobile checkout could recover 15% of abandoned carts, worth $3M annually.',
19 'data_highlight': 'revenue_opportunity'
20 },
21 {
22 'headline': 'Recommended action',
23 'visual': 'roadmap',
24 'text': 'A simplified mobile checkout with Apple Pay integration could be live in 8 weeks.',
25 'data_highlight': 'timeline'
26 }
27]

8. Thực hành

Data Storytelling Project

Exercise: Create Data Story

Python
1# Build a complete data story:
2# 1. Define audience and objective
3# 2. Structure the narrative (SCQA)
4# 3. Create supporting visualizations
5# 4. Write compelling insights
6# 5. Design executive summary
7
8# YOUR CODE HERE
💡 Xem đáp án
Python
1import pandas as pd
2import numpy as np
3import matplotlib.pyplot as plt
4
5class DataStory:
6 def __init__(self, title, audience='executive'):
7 self.title = title
8 self.audience = audience
9 self.sections = []
10
11 def add_section(self, headline, body, data=None, visual_type=None):
12 self.sections.append({
13 'headline': headline,
14 'body': body,
15 'data': data,
16 'visual_type': visual_type
17 })
18
19 def generate_executive_summary(self):
20 return {
21 'key_finding': self.sections[0]['headline'] if self.sections else '',
22 'impact': 'See detailed analysis',
23 'recommendation': self.sections[-1]['headline'] if self.sections else ''
24 }
25
26 def present(self):
27 print("=" * 60)
28 print(f"📊 {self.title}")
29 print(f" Audience: {self.audience}")
30 print("=" * 60)
31
32 for i, section in enumerate(self.sections, 1):
33 print(f"\n{'─' * 60}")
34 print(f"Section {i}: {section['headline']}")
35 print(f"{'─' * 60}")
36 print(section['body'])
37
38
39# Create sample data
40np.random.seed(42)
41
42# Monthly data
43months = pd.date_range('2024-01', periods=12, freq='M')
44data = pd.DataFrame({
45 'month': months,
46 'revenue': [1.2, 1.3, 1.25, 1.4, 1.55, 1.5, 1.6, 1.75, 1.8, 1.9, 2.1, 2.3],
47 'customers': [45000, 47000, 46500, 49000, 52000, 51000, 54000, 57000, 59000, 62000, 68000, 75000],
48 'churn_rate': [5.2, 5.5, 5.8, 6.1, 6.5, 7.0, 7.2, 7.8, 8.2, 8.5, 8.9, 9.2]
49})
50
51# Build the story
52story = DataStory(
53 title="Customer Growth vs Churn: A Strategic Paradox",
54 audience="Executive Leadership"
55)
56
57# Section 1: Situation
58story.add_section(
59 headline="Revenue and customers are growing strongly",
60 body="""
61Our business is showing impressive growth metrics:
62 Revenue YTD: $18.7M (+32% vs last year)
63 Customer base: 75,000 (+67% vs January)
64 Average revenue per customer: $250 (+8%)
65
66On the surface, everything looks great.
67 """,
68 data=data[['month', 'revenue', 'customers']],
69 visual_type='dual_axis'
70)
71
72# Section 2: Complication
73story.add_section(
74 headline="But churn is accelerating faster than growth",
75 body="""
76Hidden beneath the growth numbers is a concerning trend:
77 Churn rate: 9.2% (vs 5.2% in January - up 77%)
78 Customers lost: 6,900 this month alone
79 Lifetime value impact: -$15M in future revenue
80
81At this rate, churn will exceed acquisition by Q3.
82 """,
83 data=data[['month', 'churn_rate']],
84 visual_type='trend'
85)
86
87# Section 3: Analysis
88story.add_section(
89 headline="New customers churn 3x faster than established ones",
90 body="""
91Root cause analysis reveals:
92 New customers (< 6 months): 15% churn rate
93 Established customers (> 6 months): 5% churn rate
94
95Key drivers for new customer churn:
961. Onboarding friction - 40% cite "too complicated"
972. Value realization - 35% "didn't see results fast enough"
983. Pricing - 25% found "better deals elsewhere"
99 """,
100 visual_type='bar_comparison'
101)
102
103# Section 4: Resolution
104story.add_section(
105 headline="Recommendation: Launch 90-day success program",
106 body="""
107Proposed solution: Guided onboarding + early wins program
108
109Expected impact:
110 Reduce new customer churn from 15% to 8%
111 Save 2,100 customers annually
112 Revenue protection: $4.2M per year
113
114Investment required: $350K
115ROI: 12x in year 1
116
117Timeline: 8 weeks to MVP, 16 weeks to full rollout
118Owner: Customer Success Team
119 """,
120 visual_type='timeline'
121)
122
123# Present the story
124story.present()
125
126# Generate executive summary
127summary = story.generate_executive_summary()
128print("\n" + "=" * 60)
129print("EXECUTIVE SUMMARY")
130print("=" * 60)
131print(f"""
132KEY FINDING: While revenue grew 32%, churn increased 77% -
133threatening $15M in future revenue.
134
135ROOT CAUSE: New customers churn 3x faster due to poor onboarding.
136
137RECOMMENDATION: Launch 90-day success program
138 Cost: $350K
139 Benefit: $4.2M annual revenue protection
140 ROI: 12x
141 Timeline: 16 weeks
142
143DECISION NEEDED: Approve budget and team allocation by EOW.
144""")
145
146# Create supporting visuals
147fig, axes = plt.subplots(2, 2, figsize=(14, 10))
148
149# Visual 1: Revenue trend (good news)
150ax1 = axes[0, 0]
151ax1.fill_between(data['month'], data['revenue'], alpha=0.3, color='green')
152ax1.plot(data['month'], data['revenue'], 'go-', linewidth=2)
153ax1.set_ylabel('Revenue ($M)', color='green')
154ax1.set_title('📈 Revenue Growing Steadily', fontsize=12, fontweight='bold')
155ax1.annotate('+32% YTD', xy=(data['month'].iloc[-1], data['revenue'].iloc[-1]),
156 fontsize=11, color='green', fontweight='bold')
157
158# Visual 2: Churn trend (bad news)
159ax2 = axes[0, 1]
160ax2.fill_between(data['month'], data['churn_rate'], alpha=0.3, color='red')
161ax2.plot(data['month'], data['churn_rate'], 'ro-', linewidth=2)
162ax2.set_ylabel('Churn Rate (%)', color='red')
163ax2.set_title('⚠️ But Churn is Accelerating', fontsize=12, fontweight='bold')
164ax2.annotate('+77%', xy=(data['month'].iloc[-1], data['churn_rate'].iloc[-1]),
165 fontsize=11, color='red', fontweight='bold')
166
167# Visual 3: Churn by tenure
168ax3 = axes[1, 0]
169tenure_groups = ['< 6 months', '6-12 months', '> 12 months']
170churn_by_tenure = [15, 8, 5]
171colors = ['red' if c > 10 else 'orange' if c > 6 else 'green' for c in churn_by_tenure]
172bars = ax3.bar(tenure_groups, churn_by_tenure, color=colors)
173ax3.set_ylabel('Churn Rate (%)')
174ax3.set_title('🔍 New Customers Churn 3x More', fontsize=12, fontweight='bold')
175ax3.bar_label(bars, fmt='%.0f%%')
176ax3.axhline(8, color='gray', linestyle='--', alpha=0.5, label='Target')
177
178# Visual 4: Impact summary
179ax4 = axes[1, 1]
180ax4.axis('off')
181summary_text = """
182
183 RECOMMENDATION SUMMARY
184
185
186 Investment: $350,000
187
188 Expected ROI: 12x Year 1
189
190 Customers Saved: 2,100/year
191
192 Revenue Protected: $4.2M/year
193
194 Timeline: 16 weeks
195
196
197
198 ACTION REQUIRED
199 Approve by end of week
200"""
201ax4.text(0.5, 0.5, summary_text, transform=ax4.transAxes,
202 fontsize=11, fontfamily='monospace',
203 verticalalignment='center', horizontalalignment='center',
204 bbox=dict(boxstyle='round', facecolor='lightyellow', alpha=0.8))
205
206plt.suptitle('Customer Growth vs Churn Analysis', fontsize=14, fontweight='bold', y=1.02)
207plt.tight_layout()
208plt.savefig('data_story_visuals.png', dpi=150, bbox_inches='tight')
209plt.show()
210
211print("\n✅ Data story complete!")

9. Tổng kết

TopicKey Concepts
AudienceExecutive, Technical, Operations - tailor accordingly
StructureSCQA, Pyramid Principle, Three-Act
VisualsRight chart type, focus attention, highlight insights
WritingLead with insight, avoid jargon, actionable
PresentationHeadline-driven slides, clear flow

Bài tiếp theo: Executive Reporting