数据可视化资源专题¶
Data Visualization Resources
📚 核心理论¶
经典书籍¶
| 书名 | 作者 | 难度 | 推荐理由 |
|---|---|---|---|
| 《The Visual Display of Quantitative Information》 | Edward Tufte | ⭐⭐⭐⭐ | 可视化经典之作 |
| 《Storytelling with Data》 | Cole Nussbaumer Knaflic | ⭐⭐ | 商业报告必备 |
| 《Data Visualization: A Practical Introduction》 | Kieran Healy | ⭐⭐ | R/ggplot2 实战 |
| 《Python 数据可视化手册》 | Michael Beyeler | ⭐⭐⭐ | Python 工具大全 |
| 《信息可视化》 | 王春茂 | ⭐⭐⭐ | 中文理论教材 |
在线阅读: - 《Data Visualization: A Practical Introduction》: 链接
🎓 设计原则¶
核心原则¶
graph TB
A[数据可视化] --> B[准确性]
A --> C[清晰性]
A --> D[美观性]
A --> E[有效性]
B --> B1[数据准确]
B --> B2[比例适当]
B --> B3[避免误导]
C --> C1[标签清晰]
C --> C2[层次分明]
C --> C3[重点突出]
D --> D1[色彩和谐]
D --> D2[布局均衡]
D --> D3[风格统一]
E --> E1[传达洞察]
E --> E2[支持决策]
E --> E3[易于理解]
常见错误¶
| 错误类型 | 说明 | 改进方案 |
|---|---|---|
| 3D 图表 | 造成视觉扭曲 | 使用 2D 图表 |
| 双 Y 轴 | 容易产生误导 | 分开展示或标准化 |
| 截断 Y 轴 | 夸大差异 | Y 轴从 0 开始 |
| 过多颜色 | 分散注意力 | 限制颜色数量 |
| 饼图过多类别 | 难以比较 | 使用条形图 |
| 缺少标签 | 信息不完整 | 添加标题、轴标签 |
🛠️ Python 工具库¶
Matplotlib¶
import matplotlib.pyplot as plt
import numpy as np
# 1. 基础折线图
plt.figure(figsize=(10, 6))
plt.plot([1, 2, 3, 4], [1, 4, 9, 16], 'bo-', linewidth=2, markersize=8)
plt.xlabel('X Axis')
plt.ylabel('Y Axis')
plt.title('Simple Line Plot')
plt.grid(True, alpha=0.3)
plt.show()
# 2. 多子图
fig, axes = plt.subplots(2, 2, figsize=(12, 10))
axes[0, 0].plot([1, 2, 3], [1, 2, 3])
axes[0, 0].set_title('Subplot 1')
axes[0, 1].scatter([1, 2, 3], [3, 2, 1])
axes[0, 1].set_title('Subplot 2')
axes[1, 0].bar(['A', 'B', 'C'], [10, 20, 30])
axes[1, 0].set_title('Subplot 3')
axes[1, 1].hist(np.random.randn(1000), bins=30, alpha=0.7)
axes[1, 1].set_title('Subplot 4')
plt.tight_layout()
plt.show()
Seaborn¶
import seaborn as sns
import pandas as pd
# 加载示例数据
tips = sns.load_dataset('tips')
# 1. 关系图
sns.relplot(data=tips, x='total_bill', y='tip', hue='smoker', style='time', size='size')
# 2. 分类图
plt.figure(figsize=(12, 6))
sns.boxplot(data=tips, x='day', y='total_bill', hue='sex')
plt.title('Bill Amount by Day and Gender')
plt.show()
# 3. 分布图
plt.figure(figsize=(10, 6))
sns.histplot(data=tips, x='total_bill', kde=True, hue='sex', multiple='stack')
plt.show()
# 4. 热力图
correlation = tips.corr(numeric_only=True)
plt.figure(figsize=(8, 6))
sns.heatmap(correlation, annot=True, cmap='coolwarm', center=0)
plt.title('Correlation Matrix')
plt.show()
Plotly(交互式)¶
import plotly.express as px
import plotly.graph_objects as go
# 1. 交互式散点图
df = px.data.iris()
fig = px.scatter(df, x='sepal_width', y='sepal_length',
color='species', size='petal_length',
hover_data=['petal_width'],
title='Iris Dataset')
fig.show()
# 2. 交互式折线图
df = px.data.stocks()
fig = px.line(df, x='date', y=['GOOG', 'AAPL', 'AMZN', 'FB'],
title='Stock Prices 2018-2020')
fig.update_layout(xaxis_title='Date', yaxis_title='Price')
fig.show()
# 3. 交互式地图
df = px.data.gapminder().query("year==2007")
fig = px.scatter_geo(df, locations="iso_alpha",
color="continent",
hover_name="country",
size="pop",
projection="natural earth",
title='World Population 2007')
fig.show()
图表选择指南¶
graph TD
A[数据可视化目标] --> B[比较]
A --> C[构成]
A --> D[分布]
A --> E[关系]
A --> F[趋势]
B --> B1[条形图]
B --> B2[柱状图]
B --> B3[雷达图]
C --> C1[饼图]
C --> C2[环形图]
C --> C3[堆叠面积图]
D --> D1[直方图]
D --> D2[箱线图]
D --> D3[小提琴图]
E --> E1[散点图]
E --> E2[气泡图]
E --> E3[热力图]
F --> F1[折线图]
F --> F2[面积图]
F --> F3[时间序列]
📊 实战案例¶
销售仪表板¶
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
# 设置样式
plt.style.use('seaborn-v0_8')
sns.set_palette("husl")
# 创建仪表板
fig = plt.figure(figsize=(20, 12))
fig.suptitle('Sales Dashboard - 2024', fontsize=20, fontweight='bold')
# 1. 月度销售趋势
ax1 = plt.subplot2grid((3, 3), (0, 0), colspan=2)
monthly_sales = df.groupby('month')['revenue'].sum()
ax1.plot(monthly_sales.index, monthly_sales.values, marker='o', linewidth=2)
ax1.set_title('Monthly Revenue Trend')
ax1.set_xlabel('Month')
ax1.set_ylabel('Revenue ($)')
ax1.grid(True, alpha=0.3)
# 2. 产品分类销售
ax2 = plt.subplot2grid((3, 3), (0, 2))
category_sales = df.groupby('category')['revenue'].sum().sort_values()
ax2.barh(category_sales.index, category_sales.values)
ax2.set_title('Sales by Category')
ax2.set_xlabel('Revenue ($)')
# 3. 地区分布
ax3 = plt.subplot2grid((3, 3), (1, 0))
region_sales = df.groupby('region')['revenue'].sum()
colors = plt.cm.Set3(range(len(region_sales)))
ax3.pie(region_sales.values, labels=region_sales.index, autopct='%1.1f%%', colors=colors)
ax3.set_title('Regional Distribution')
# 4. 客户 RFM 分群
ax4 = plt.subplot2grid((3, 3), (1, 1), colspan=2)
rfm_segments = df.groupby('segment')['customer_id'].nunique()
ax4.bar(rfm_segments.index, rfm_segments.values, color=['#2ecc71', '#3498db', '#95a5a6', '#e74c3c'])
ax4.set_title('Customer Segments (RFM)')
ax4.set_xlabel('Segment')
ax4.set_ylabel('Customer Count')
plt.xticks(rotation=45)
# 5. 转化率漏斗
ax5 = plt.subplot2grid((3, 3), (2, 0), colspan=3)
funnel_stages = ['Page View', 'Add to Cart', 'Checkout', 'Purchase']
funnel_values = [10000, 3500, 1800, 950]
ax5.barh(funnel_stages, funnel_values, color='#3498db')
ax5.set_title('Conversion Funnel')
ax5.set_xlabel('Users')
for i, v in enumerate(funnel_values):
ax5.text(v + 100, i, str(v))
plt.tight_layout()
plt.savefig('sales_dashboard.png', dpi=300, bbox_inches='tight')
plt.show()
相关性分析¶
import seaborn as sns
import matplotlib.pyplot as plt
# 计算相关性矩阵
corr_matrix = df.corr(numeric_only=True)
# 创建热力图
plt.figure(figsize=(14, 12))
mask = np.triu(np.ones_like(corr_matrix, dtype=bool)) # 上三角掩码
sns.heatmap(corr_matrix,
mask=mask,
annot=True,
fmt='.2f',
cmap='RdBu_r',
center=0,
square=True,
linewidths=1,
cbar_kws={"shrink": 0.8})
plt.title('Feature Correlation Heatmap', fontsize=16, fontweight='bold')
plt.tight_layout()
plt.show()
# 散点图矩阵
sns.pairplot(df[['feature1', 'feature2', 'feature3', 'target']],
hue='target',
plot_kws={'alpha': 0.6, 's': 50},
diag_kws={'bins': 20})
plt.suptitle('Pair Plot of Features', y=1.02)
plt.show()
🎨 配色方案¶
推荐色板¶
# Seaborn 色板
sns.color_palette('husl', 10) # 鲜明多彩
sns.color_palette('Set2', 8) # 柔和色板
sns.color_palette('coolwarm', 10) # diverging
sns.color_palette('viridis', 10) # 连续渐变
# Matplotlib 色板
plt.cm.tab10.colors # 分类色板(10 色)
plt.cm.Paired.colors # 配对色板
plt.cm.RdYlBu # 红 - 黄 - 蓝渐变
配色原则¶
| 场景 | 推荐色板 | 注意事项 |
|---|---|---|
| 分类数据 | Set1, Set2, tab10 | 限制类别数量 |
| 连续数据 | viridis, plasma | 避免彩虹色 |
| 正负偏离 | RdBu, coolwarm | 中性色在中间 |
| 打印友好 | colorblind | 考虑色盲用户 |
🔍 最佳实践¶
图表设计清单¶
- 标题清晰,说明图表目的
- 轴标签完整,包含单位
- 图例位置合理,不遮挡数据
- 颜色使用有意义,非装饰性
- 网格线适度,不喧宾夺主
- 数据标签在必要时添加
- 避免 3D 效果和过度装饰
- Y 轴从 0 开始(除非有特殊原因)
- 保持一致的样式和配色
- 添加数据来源说明
故事化呈现¶
graph LR
A[数据] --> B[洞察]
B --> C[故事]
C --> D[行动]
A --> A1[整理数据]
B --> B1[发现模式]
C --> C1[构建叙事]
D --> D1[决策建议]
🔗 更多资源¶
灵感网站¶
- Data Viz Catalogue - 图表类型百科
- Makeover Monday - 可视化改进社区
- Tableau Public - 优秀作品集
工具比较¶
- Python Graph Gallery - Matplotlib/Seaborn/Plotly 示例
- Charticulator - 自定义图表设计工具
最后更新: 2026-06-01