Data Visualization
Overview
Data visualization transforms complex data into clear, compelling visual representations that reveal patterns, trends, and insights for storytelling and decision-making.
When to Use
- Exploratory data analysis and pattern discovery
- Communicating insights to stakeholders
- Comparing distributions and relationships
- Presenting findings in reports and dashboards
- Identifying outliers and anomalies visually
- Creating publication-ready charts and graphs
Visualization Types
- Distributions: Histograms, KDE, violin plots
- Relationships: Scatter plots, line plots, heatmaps
- Comparisons: Bar charts, box plots, ridge plots
- Compositions: Pie charts, stacked bars, treemaps
- Temporal: Line plots, area charts, time series
- Multivariate: Pair plots, correlation heatmaps
Design Principles
- Choose appropriate chart type for data
- Minimize ink-to-data ratio
- Use color purposefully
- Label clearly and completely
- Maintain consistent scales
- Consider accessibility
Implementation with Python
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from matplotlib.gridspec import GridSpec
# Set style
sns.set_style("whitegrid")
plt.rcParams['figure.figsize'] = (12, 6)
# Generate sample data
np.random.seed(42)
n = 500
data = pd.DataFrame({
'age': np.random.uniform(20, 70, n),
'income': np.random.exponential(50000, n),
'education_years': np.random.uniform(12, 20, n),
'category': np.random.choice(['A', 'B', 'C'], n),
'region': np.random.choice(['North', 'South', 'East', 'West'], n),
'satisfaction': np.random.uniform(1, 5, n),
'purchased': np.random.choice([0, 1], n),
})
print(data.head())
# 1. Distribution Plots
fig, axes = plt.subplots(2, 2, figsize=(12, 8))
# Histogram
axes[0, 0].hist(data['age'], bins=30, color='skyblue', edgecolor='black')
axes[0, 0].set_title('Age Distribution (Histogram)')
axes[0, 0].set_xlabel('Age')
axes[0, 0].set_ylabel('Frequency')
# KDE plot
data['income'].plot(kind='kde', ax=axes[0, 1], color='green', linewidth=2)
axes[0, 1].set_title('Income Distribution (KDE)')
axes[0, 1].set_xlabel('Income')
# Box plot
sns.boxplot(data=data, y='satisfaction', x='category', ax=axes[1, 0], palette='Set2')
axes[1, 0].set_title('Satisfaction by Category (Box Plot)')
# Violin plot
sns.violinplot(data=data, y='age', x='category', ax=axes[1, 1], palette='Set2')
axes[1, 1].set_title('Age by Category (Violin Plot)')
plt.tight_layout()
plt.show()
# 2. Relationship Plots
fig, axes = plt.subplots(2, 2, figsize=(12, 8))
# Scatter plot
axes[0, 0].scatter(data['age'], data['income'], alpha=0.5, s=30)
axes[0, 0].set_title('Age vs Income (Scatter Plot)')
axes[0, 0].set_xlabel('Age')
axes[0, 0].set_ylabel('Income')
# Scatter with regression line
sns.regplot(x='age', y='income', data=data, ax=axes[0, 1], scatter_kws={'alpha': 0.5})
axes[0, 1].set_title('Age vs Income (with Regression Line)')
# Joint plot alternative
ax_hex = axes[1, 0]
hexbin = ax_hex.hexbin(data['age'], data['income'], gridsize=15, cmap='YlOrRd')
ax_hex.set_title('Age vs Income (Hex Bin)')
ax_hex.set_xlabel('Age')
ax_hex.set_ylabel('Income')
# Bubble plot
scatter = axes[1, 1].scatter(
data['age'], data['income'], s=data['satisfaction']*50,
c=data['satisfaction'], cmap='viridis', alpha=0.6, edgecolors='black'
)
axes[1, 1].set_title('Age vs Income (Bubble Plot)')
axes[1, 1].set_xlabel('Age')
axes[1, 1].set_ylabel('Income')
plt.colorbar(scatter, ax=axes[1, 1], label='Satisfaction')
plt.tight_layout()
plt.show()
# 3. Comparison Plots
fig, axes = plt.subplots(2, 2, figsize=(12, 8))
# Bar plot
category_counts = data['category'].value_counts()
axes[0, 0].bar(category_counts.index, category_counts.values, color='skyblue', edgecolor='black')
axes[0, 0].set_title('Category Distribution (Bar Chart)')
axes[0, 0].set_ylabel('Count')
# Grouped bar plot
grouped_data = data.groupby(['category', 'region']).size().unstack()
grouped_data.plot(kind='bar', ax=axes[0, 1], edgecolor='black')
axes[0, 1].set_title('Category by Region (Grouped Bar)')
axes[0, 1].set_ylabel('Count')
axes[0, 1].legend(title='Region')
# Stacked bar plot
grouped_data.plot(kind='bar', stacked=True, ax=axes[1, 0], edgecolor='black')
axes[1, 0].set_title('Category by Region (Stacked Bar)')
axes[1, 0].set_ylabel('Count')
# Horizontal bar plot
region_counts = data['region'].value_counts()
axes[1, 1].barh(region_counts.index, region_counts.values, color='lightcoral', edgecolor='black')
axes[1, 1].set_title('Region Distribution (Horizontal Bar)')
axes[1, 1].set_xlabel('Count')
plt.tight_layout()
plt.show()
# 4. Correlation and Heatmaps
numeric_cols = data[['age', 'income', 'education_years', 'satisfaction']].corr()
fig, axes = plt.subplots(1, 2, figsize=(14, 5))
# Correlation heatmap
sns.heatmap(numeric_cols, annot=True, fmt='.2f', cmap='coolwarm', center=0,
square=True, ax=axes[0], cbar_kws={'label': 'Correlation'})
axes[0].set_title('Correlation Matrix Heatmap')
# Clustermap alternative
from scipy.cluster.hierarchy import dendrogram, linkage
from scipy.spatial.distance import pdist, squareform
# Create a simpler heatmap for category averages
category_avg = data.groupby('category')[['age', 'income', 'education_years', 'satisfaction']].mean()
sns.heatmap(category_avg.T, annot=True, fmt='.1f', cmap='YlGnBu', ax=axes[1],
cbar_kws={'label': 'Average Value'})
axes[1].set_title('Average Values by Category')
plt.tight_layout()
plt.show()
# 5. Pair Plot
pair_cols = ['age', 'income', 'education_years', 'satisfaction']
plt.figure(figsize=(12, 10))
pair_plot = sns.pairplot(data[pair_cols], diag_kind='hist', corner=False)
pair_plot.fig.suptitle('Pair Plot Matrix', y=1.00)
plt.show()
# 6. Multi-dimensional Visualization
fig = plt.figure(figsize=(14, 6))
gs = GridSpec(2, 3, figure=fig)
# Subplots with different aspects
ax1 = fig.add_subplot(gs[0, 0])
ax1.scatter(data['age'], data['income'], c=data['satisfaction'], cmap='viridis', alpha=0.6)
ax1.set_title('Age vs Income (colored by Satisfaction)')
ax1.set_xlabel('Age')
ax1.set_ylabel('Income')
ax2 = fig.add_subplot(gs[0, 1])
for cat in data['category'].unique():
subset = data[data['category'] == cat]
ax2.scatter(subset['age'], subset['income'], label=cat, alpha=0.6)
ax2.set_title('Age vs Income (by Category)')
ax2.set_xlabel('Age')
ax2.set_ylabel('Income')
ax2.legend()
ax3 = fig.add_subplot(gs[0, 2])
sns.boxplot(data=data, x='region', y='income', ax=ax3, palette='Set2')
ax3.set_title('Income Distribution by Region')
ax4 = fig.add_subplot(gs[1, 0])
data.groupby('category')['satisfaction'].mean().plot(kind='bar', ax=ax4, color='skyblue', edgecolor='black')
ax4.set_title('Average Satisfaction by Category')
ax4.set_ylabel('Satisfaction')
ax4.set_xlabel('Category')
ax5 = fig.add_subplot(gs[1, 1:])
region_category = pd.crosstab(data['region'], data['category'])
region_category.plot(kind='bar', ax=ax5, edgecolor='black')
ax5.set_title('Region vs Category Distribution')
ax5.set_ylabel('Count')
ax5.set_xlabel('Region')
ax5.legend(title='Category')
plt.tight_layout()
plt.show()
# 7. Time Series Visualization (if temporal data)
dates = pd.date_range('2023-01-01', periods=len(data))
data['date'] = dates
data['cumulative_income'] = data['income'].cumsum()
fig, axes = plt.subplots(2, 1, figsize=(12, 8))
# Line plot
axes[0].plot(data['date'], data['income'], linewidth=1, alpha=0.7, label='Income')
axes[0].fill_between(data['date'], data['income'], alpha=0.3)
axes[0].set_title('Income Over Time')
axes[0].set_ylabel('Income')
axes[0].grid(True, alpha=0.3)
axes[0].legend()
# Area plot
axes[1].plot(data['date'], data['cumulative_income'], linewidth=2, color='green')
axes[1].fill_between(data['date'], data['cumulative_income'], alpha=0.3, color='green')
axes[1].set_title('Cumulative Income Over Time')
axes[1].set_ylabel('Cumulative Income')
axes[1].set_xlabel('Date')
axes[1].grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
# 8. Composition Visualization
fig, axes = plt.subplots(1, 2, figsize=(12, 5))
# Pie chart
category_counts = data['category'].value_counts()
colors = ['#ff9999', '#66b3ff', '#99ff99']
axes[0].pie(category_counts.values, labels=category_counts.index, autopct='%1.1f%%',
colors=colors, startangle=90)
axes[0].set_title('Category Distribution (Pie Chart)')
# Donut chart
axes[1].pie(category_counts.values, labels=category_counts.index, autopct='%1.1f%%',
colors=colors, startangle=90, wedgeprops=dict(width=0.5, edgecolor='white'))
axes[1].set_title('Category Distribution (Donut Chart)')
plt.tight_layout()
plt.show()
# 9. Dashboard-style Visualization
fig = plt.figure(figsize=(16, 10))
gs = GridSpec(3, 3, figure=fig, hspace=0.3, wspace=0.3)
# Key metrics
ax_metric = fig.add_subplot(gs[0, :])
ax_metric.axis('off')
metrics_text = f"""
Average Age: {data['age'].mean():.1f} | Average Income: ${data['income'].mean():.0f} |
Average Satisfaction: {data['satisfaction'].mean():.2f} | Purchase Rate: {(data['purchased'].mean()*100):.1f}%
"""
ax_metric.text(0.5, 0.5, metrics_text, ha='center', va='center', fontsize=12,
bbox=dict(boxstyle='round', facecolor='lightblue', alpha=0.7))
# Subplots
ax1 = fig.add_subplot(gs[1, 0])
data['age'].hist(bins=20, ax=ax1, color='skyblue', edgecolor='black')
ax1.set_title('Age Distribution')
ax2 = fig.add_subplot(gs[1, 1])
category_counts.plot(kind='bar', ax=ax2, color='lightcoral', edgecolor='black')
ax2.set_title('Category Counts')
ax3 = fig.add_subplot(gs[1, 2])
data.groupby('category')['satisfaction'].mean().plot(kind='bar', ax=ax3, color='lightgreen', edgecolor='black')
ax3.set_title('Avg Satisfaction by Category')
ax4 = fig.add_subplot(gs[2, :2])
sns.boxplot(data=data, x='region', y='income', ax=ax4, palette='Set2')
ax4.set_title('Income by Region')
ax5 = fig.add_subplot(gs[2, 2])
data['satisfaction'].value_counts().sort_index().plot(kind='bar', ax=ax5, color='orange', edgecolor='black')
ax5.set_title('Satisfaction Scores')
plt.suptitle('Data Analytics Dashboard', fontsize=16, fontweight='bold', y=0.995)
plt.show()
print("Visualization examples completed!")
Visualization Best Practices
- Choose chart type based on data type and question
- Use consistent color schemes
- Label axes clearly with units
- Include title and legend
- Avoid 3D charts when 2D suffices
- Make fonts large and readable
- Consider colorblind-friendly palettes
Common Chart Types
- Bar charts: Categorical comparisons
- Line plots: Trends over time
- Scatter plots: Relationships between variables
- Histograms: Distributions
- Heatmaps: Matrix data
- Box plots: Distribution with quartiles
Deliverables
- Exploratory visualizations
- Publication-ready charts
- Interactive dashboard mockups
- Statistical plots with annotations
- Trend analysis visualizations
- Comparative analysis charts
- Summary infographics
1---2name: data-visualization-53description: Create effective visualizations using matplotlib and seaborn for exploratory analysis, presenting insights, and communicating findings with business stakeholders4---5
6# Data Visualization
7
8## Overview
9
10Data visualization transforms complex data into clear, compelling visual representations that reveal patterns, trends, and insights for storytelling and decision-making.
11
12## When to Use
13
14- Exploratory data analysis and pattern discovery
15- Communicating insights to stakeholders
16- Comparing distributions and relationships
17- Presenting findings in reports and dashboards
18- Identifying outliers and anomalies visually
19- Creating publication-ready charts and graphs
20
21## Visualization Types
22
23- **Distributions**: Histograms, KDE, violin plots
24- **Relationships**: Scatter plots, line plots, heatmaps
25- **Comparisons**: Bar charts, box plots, ridge plots
26- **Compositions**: Pie charts, stacked bars, treemaps
27- **Temporal**: Line plots, area charts, time series
28- **Multivariate**: Pair plots, correlation heatmaps
29
30## Design Principles
31
32- Choose appropriate chart type for data
33- Minimize ink-to-data ratio
34- Use color purposefully
35- Label clearly and completely
36- Maintain consistent scales
37- Consider accessibility
38
39## Implementation with Python
40
41```python
42import pandas as pd
43import numpy as np
44import matplotlib.pyplot as plt
45import seaborn as sns
46from matplotlib.gridspec import GridSpec
47
48# Set style
49sns.set_style("whitegrid")
50plt.rcParams['figure.figsize'] = (12, 6)
51
52# Generate sample data
53np.random.seed(42)
54n = 500
55data = pd.DataFrame({
56 'age': np.random.uniform(20, 70, n),
57 'income': np.random.exponential(50000, n),
58 'education_years': np.random.uniform(12, 20, n),
59 'category': np.random.choice(['A', 'B', 'C'], n),
60 'region': np.random.choice(['North', 'South', 'East', 'West'], n),
61 'satisfaction': np.random.uniform(1, 5, n),
62 'purchased': np.random.choice([0, 1], n),
63})
64
65print(data.head())
66
67# 1. Distribution Plots
68fig, axes = plt.subplots(2, 2, figsize=(12, 8))
69
70# Histogram
71axes[0, 0].hist(data['age'], bins=30, color='skyblue', edgecolor='black')
72axes[0, 0].set_title('Age Distribution (Histogram)')
73axes[0, 0].set_xlabel('Age')
74axes[0, 0].set_ylabel('Frequency')
75
76# KDE plot
77data['income'].plot(kind='kde', ax=axes[0, 1], color='green', linewidth=2)
78axes[0, 1].set_title('Income Distribution (KDE)')
79axes[0, 1].set_xlabel('Income')
80
81# Box plot
82sns.boxplot(data=data, y='satisfaction', x='category', ax=axes[1, 0], palette='Set2')
83axes[1, 0].set_title('Satisfaction by Category (Box Plot)')
84
85# Violin plot
86sns.violinplot(data=data, y='age', x='category', ax=axes[1, 1], palette='Set2')
87axes[1, 1].set_title('Age by Category (Violin Plot)')
88
89plt.tight_layout()
90plt.show()
91
92# 2. Relationship Plots
93fig, axes = plt.subplots(2, 2, figsize=(12, 8))
94
95# Scatter plot
96axes[0, 0].scatter(data['age'], data['income'], alpha=0.5, s=30)
97axes[0, 0].set_title('Age vs Income (Scatter Plot)')
98axes[0, 0].set_xlabel('Age')
99axes[0, 0].set_ylabel('Income')
100
101# Scatter with regression line
102sns.regplot(x='age', y='income', data=data, ax=axes[0, 1], scatter_kws={'alpha': 0.5})
103axes[0, 1].set_title('Age vs Income (with Regression Line)')
104
105# Joint plot alternative
106ax_hex = axes[1, 0]
107hexbin = ax_hex.hexbin(data['age'], data['income'], gridsize=15, cmap='YlOrRd')
108ax_hex.set_title('Age vs Income (Hex Bin)')
109ax_hex.set_xlabel('Age')
110ax_hex.set_ylabel('Income')
111
112# Bubble plot
113scatter = axes[1, 1].scatter(
114 data['age'], data['income'], s=data['satisfaction']*50,
115 c=data['satisfaction'], cmap='viridis', alpha=0.6, edgecolors='black'
116)
117axes[1, 1].set_title('Age vs Income (Bubble Plot)')
118axes[1, 1].set_xlabel('Age')
119axes[1, 1].set_ylabel('Income')
120plt.colorbar(scatter, ax=axes[1, 1], label='Satisfaction')
121
122plt.tight_layout()
123plt.show()
124
125# 3. Comparison Plots
126fig, axes = plt.subplots(2, 2, figsize=(12, 8))
127
128# Bar plot
129category_counts = data['category'].value_counts()
130axes[0, 0].bar(category_counts.index, category_counts.values, color='skyblue', edgecolor='black')
131axes[0, 0].set_title('Category Distribution (Bar Chart)')
132axes[0, 0].set_ylabel('Count')
133
134# Grouped bar plot
135grouped_data = data.groupby(['category', 'region']).size().unstack()
136grouped_data.plot(kind='bar', ax=axes[0, 1], edgecolor='black')
137axes[0, 1].set_title('Category by Region (Grouped Bar)')
138axes[0, 1].set_ylabel('Count')
139axes[0, 1].legend(title='Region')
140
141# Stacked bar plot
142grouped_data.plot(kind='bar', stacked=True, ax=axes[1, 0], edgecolor='black')
143axes[1, 0].set_title('Category by Region (Stacked Bar)')
144axes[1, 0].set_ylabel('Count')
145
146# Horizontal bar plot
147region_counts = data['region'].value_counts()
148axes[1, 1].barh(region_counts.index, region_counts.values, color='lightcoral', edgecolor='black')
149axes[1, 1].set_title('Region Distribution (Horizontal Bar)')
150axes[1, 1].set_xlabel('Count')
151
152plt.tight_layout()
153plt.show()
154
155# 4. Correlation and Heatmaps
156numeric_cols = data[['age', 'income', 'education_years', 'satisfaction']].corr()
157
158fig, axes = plt.subplots(1, 2, figsize=(14, 5))
159
160# Correlation heatmap
161sns.heatmap(numeric_cols, annot=True, fmt='.2f', cmap='coolwarm', center=0,
162 square=True, ax=axes[0], cbar_kws={'label': 'Correlation'})
163axes[0].set_title('Correlation Matrix Heatmap')
164
165# Clustermap alternative
166from scipy.cluster.hierarchy import dendrogram, linkage
167from scipy.spatial.distance import pdist, squareform
168
169# Create a simpler heatmap for category averages
170category_avg = data.groupby('category')[['age', 'income', 'education_years', 'satisfaction']].mean()
171sns.heatmap(category_avg.T, annot=True, fmt='.1f', cmap='YlGnBu', ax=axes[1],
172 cbar_kws={'label': 'Average Value'})
173axes[1].set_title('Average Values by Category')
174
175plt.tight_layout()
176plt.show()
177
178# 5. Pair Plot
179pair_cols = ['age', 'income', 'education_years', 'satisfaction']
180plt.figure(figsize=(12, 10))
181pair_plot = sns.pairplot(data[pair_cols], diag_kind='hist', corner=False)
182pair_plot.fig.suptitle('Pair Plot Matrix', y=1.00)
183plt.show()
184
185# 6. Multi-dimensional Visualization
186fig = plt.figure(figsize=(14, 6))
187gs = GridSpec(2, 3, figure=fig)
188
189# Subplots with different aspects
190ax1 = fig.add_subplot(gs[0, 0])
191ax1.scatter(data['age'], data['income'], c=data['satisfaction'], cmap='viridis', alpha=0.6)
192ax1.set_title('Age vs Income (colored by Satisfaction)')
193ax1.set_xlabel('Age')
194ax1.set_ylabel('Income')
195
196ax2 = fig.add_subplot(gs[0, 1])
197for cat in data['category'].unique():
198 subset = data[data['category'] == cat]
199 ax2.scatter(subset['age'], subset['income'], label=cat, alpha=0.6)
200ax2.set_title('Age vs Income (by Category)')
201ax2.set_xlabel('Age')
202ax2.set_ylabel('Income')
203ax2.legend()
204
205ax3 = fig.add_subplot(gs[0, 2])
206sns.boxplot(data=data, x='region', y='income', ax=ax3, palette='Set2')
207ax3.set_title('Income Distribution by Region')
208
209ax4 = fig.add_subplot(gs[1, 0])
210data.groupby('category')['satisfaction'].mean().plot(kind='bar', ax=ax4, color='skyblue', edgecolor='black')
211ax4.set_title('Average Satisfaction by Category')
212ax4.set_ylabel('Satisfaction')
213ax4.set_xlabel('Category')
214
215ax5 = fig.add_subplot(gs[1, 1:])
216region_category = pd.crosstab(data['region'], data['category'])
217region_category.plot(kind='bar', ax=ax5, edgecolor='black')
218ax5.set_title('Region vs Category Distribution')
219ax5.set_ylabel('Count')
220ax5.set_xlabel('Region')
221ax5.legend(title='Category')
222
223plt.tight_layout()
224plt.show()
225
226# 7. Time Series Visualization (if temporal data)
227dates = pd.date_range('2023-01-01', periods=len(data))
228data['date'] = dates
229data['cumulative_income'] = data['income'].cumsum()
230
231fig, axes = plt.subplots(2, 1, figsize=(12, 8))
232
233# Line plot
234axes[0].plot(data['date'], data['income'], linewidth=1, alpha=0.7, label='Income')
235axes[0].fill_between(data['date'], data['income'], alpha=0.3)
236axes[0].set_title('Income Over Time')
237axes[0].set_ylabel('Income')
238axes[0].grid(True, alpha=0.3)
239axes[0].legend()
240
241# Area plot
242axes[1].plot(data['date'], data['cumulative_income'], linewidth=2, color='green')
243axes[1].fill_between(data['date'], data['cumulative_income'], alpha=0.3, color='green')
244axes[1].set_title('Cumulative Income Over Time')
245axes[1].set_ylabel('Cumulative Income')
246axes[1].set_xlabel('Date')
247axes[1].grid(True, alpha=0.3)
248
249plt.tight_layout()
250plt.show()
251
252# 8. Composition Visualization
253fig, axes = plt.subplots(1, 2, figsize=(12, 5))
254
255# Pie chart
256category_counts = data['category'].value_counts()
257colors = ['#ff9999', '#66b3ff', '#99ff99']
258axes[0].pie(category_counts.values, labels=category_counts.index, autopct='%1.1f%%',
259 colors=colors, startangle=90)
260axes[0].set_title('Category Distribution (Pie Chart)')
261
262# Donut chart
263axes[1].pie(category_counts.values, labels=category_counts.index, autopct='%1.1f%%',
264 colors=colors, startangle=90, wedgeprops=dict(width=0.5, edgecolor='white'))
265axes[1].set_title('Category Distribution (Donut Chart)')
266
267plt.tight_layout()
268plt.show()
269
270# 9. Dashboard-style Visualization
271fig = plt.figure(figsize=(16, 10))
272gs = GridSpec(3, 3, figure=fig, hspace=0.3, wspace=0.3)
273
274# Key metrics
275ax_metric = fig.add_subplot(gs[0, :])
276ax_metric.axis('off')
277metrics_text = f"""
278Average Age: {data['age'].mean():.1f} | Average Income: ${data['income'].mean():.0f} |
279Average Satisfaction: {data['satisfaction'].mean():.2f} | Purchase Rate: {(data['purchased'].mean()*100):.1f}%
280"""
281ax_metric.text(0.5, 0.5, metrics_text, ha='center', va='center', fontsize=12,
282 bbox=dict(boxstyle='round', facecolor='lightblue', alpha=0.7))
283
284# Subplots
285ax1 = fig.add_subplot(gs[1, 0])
286data['age'].hist(bins=20, ax=ax1, color='skyblue', edgecolor='black')
287ax1.set_title('Age Distribution')
288
289ax2 = fig.add_subplot(gs[1, 1])
290category_counts.plot(kind='bar', ax=ax2, color='lightcoral', edgecolor='black')
291ax2.set_title('Category Counts')
292
293ax3 = fig.add_subplot(gs[1, 2])
294data.groupby('category')['satisfaction'].mean().plot(kind='bar', ax=ax3, color='lightgreen', edgecolor='black')
295ax3.set_title('Avg Satisfaction by Category')
296
297ax4 = fig.add_subplot(gs[2, :2])
298sns.boxplot(data=data, x='region', y='income', ax=ax4, palette='Set2')
299ax4.set_title('Income by Region')
300
301ax5 = fig.add_subplot(gs[2, 2])
302data['satisfaction'].value_counts().sort_index().plot(kind='bar', ax=ax5, color='orange', edgecolor='black')
303ax5.set_title('Satisfaction Scores')
304
305plt.suptitle('Data Analytics Dashboard', fontsize=16, fontweight='bold', y=0.995)
306plt.show()
307
308print("Visualization examples completed!")
309```
310
311## Visualization Best Practices
312
313- Choose chart type based on data type and question
314- Use consistent color schemes
315- Label axes clearly with units
316- Include title and legend
317- Avoid 3D charts when 2D suffices
318- Make fonts large and readable
319- Consider colorblind-friendly palettes
320
321## Common Chart Types
322
323- **Bar charts**: Categorical comparisons
324- **Line plots**: Trends over time
325- **Scatter plots**: Relationships between variables
326- **Histograms**: Distributions
327- **Heatmaps**: Matrix data
328- **Box plots**: Distribution with quartiles
329
330## Deliverables
331
332- Exploratory visualizations
333- Publication-ready charts
334- Interactive dashboard mockups
335- Statistical plots with annotations
336- Trend analysis visualizations
337- Comparative analysis charts
338- Summary infographics