Python数据可视化实战:matplotlib+seaborn+plotly从静态图到交互图全攻略
导语: 数据分析的最终产物往往是一张能说话的图表。matplotlib 是基础,seaborn 让统计图变美,plotly 则让图表动起来、交互起来。本文系统讲解三大可视化库的核心用法,从折线图、柱状图、散点图、热力图,到交互式仪表板,附带真实数据集代码,帮你从"能画图"升级到"会讲故事"。
一、matplotlib 基础与高频图表
1.1 画布与子图系统
import matplotlib.pyplot as plt
import matplotlib as mpl
import numpy as np
import pandas as pd
# 中文显示配置(Windows)
plt.rcParams['font.sans-serif'] = ['SimHei', 'Microsoft YaHei']
plt.rcParams['axes.unicode_minus'] = False
plt.rcParams['figure.dpi'] = 120
# 单图
fig, ax = plt.subplots(figsize=(10, 6))
x = np.linspace(0, 2*np.pi, 100)
ax.plot(x, np.sin(x), label='sin(x)', color='#E74C3C', linewidth=2)
ax.plot(x, np.cos(x), label='cos(x)', color='#3498DB', linewidth=2, linestyle='--')
ax.set_title('三角函数图像', fontsize=16, fontweight='bold')
ax.set_xlabel('x (弧度)')
ax.set_ylabel('y 值')
ax.legend()
ax.grid(True, alpha=0.3)
plt.tight_layout()
plt.savefig('sin_cos.png', dpi=150, bbox_inches='tight')
plt.show()
# 多子图布局
fig, axes = plt.subplots(2, 3, figsize=(15, 10))
fig.suptitle('多维度数据概览', fontsize=18, fontweight='bold')
1.2 常用图表类型
# 柱状图(对比分析)
categories = ['工程部', '市场部', 'HR', '销售部', '产品部']
values = [85000, 72000, 78000, 90000, 82000]
colors = ['#E74C3C' if v == max(values) else '#3498DB' for v in values]
fig, ax = plt.subplots(figsize=(10, 6))
bars = ax.bar(categories, values, color=colors, edgecolor='white', linewidth=0.5)
# 在柱子上显示数值
for bar, val in zip(bars, values):
ax.text(bar.get_x() + bar.get_width()/2, bar.get_height() + 500,
f'¥{val:,}', ha='center', va='bottom', fontsize=11, fontweight='bold')
ax.set_ylim(0, max(values) * 1.2)
ax.set_ylabel('平均薪资(元)')
ax.set_title('各部门平均薪资对比', fontsize=14)
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
# 散点图(分布与相关性)
np.random.seed(42)
x = np.random.normal(0, 1, 200)
y = 2 * x + np.random.normal(0, 0.5, 200)
fig, ax = plt.subplots(figsize=(8, 6))
scatter = ax.scatter(x, y, c=y, cmap='RdYlBu', alpha=0.7, s=50)
plt.colorbar(scatter, label='y值')
ax.set_title('散点图(带颜色映射)')
# 折线图(趋势分析)
dates = pd.date_range('2024-01-01', periods=12, freq='ME')
sales = [120, 135, 118, 142, 165, 180, 195, 172, 160, 148, 130, 155]
fig, ax = plt.subplots(figsize=(12, 5))
ax.plot(dates, sales, marker='o', color='#27AE60', linewidth=2, markersize=8)
ax.fill_between(dates, sales, alpha=0.2, color='#27AE60')
ax.set_title('2024年月度销售趋势', fontsize=14)
二、seaborn 统计可视化
import seaborn as sns
# 设置主题
sns.set_theme(style='whitegrid', palette='husl', font='SimHei')
# 加载示例数据集
tips = sns.load_dataset('tips')
iris = sns.load_dataset('iris')
# 分布图(直方图 + KDE)
fig, axes = plt.subplots(1, 2, figsize=(14, 5))
sns.histplot(tips['total_bill'], bins=30, kde=True, ax=axes[0], color='#3498DB')
axes[0].set_title('账单金额分布')
sns.boxplot(x='day', y='total_bill', data=tips, ax=axes[1], palette='Set2')
axes[1].set_title('各日期账单分布')
plt.tight_layout()
# 热力图(相关性分析必用)
corr_matrix = iris.drop('species', axis=1).corr()
fig, ax = plt.subplots(figsize=(8, 6))
sns.heatmap(corr_matrix,
annot=True, # 显示数值
fmt='.2f', # 小数格式
cmap='RdYlGn', # 颜色方案
vmin=-1, vmax=1, # 颜色范围
square=True,
linewidths=0.5,
ax=ax)
ax.set_title('特征相关性热力图', fontsize=14)
# 配对关系图(EDA利器)
g = sns.pairplot(iris, hue='species', diag_kind='kde',
plot_kws={'alpha': 0.7})
g.fig.suptitle('鸢尾花数据集特征配对关系', y=1.02)
# 小提琴图(分布形状 + 箱线图合体)
fig, ax = plt.subplots(figsize=(10, 6))
sns.violinplot(x='day', y='tip', data=tips, hue='sex', split=True,
palette={'Male': '#3498DB', 'Female': '#E91E63'}, ax=ax)
ax.set_title('各日期小费分布(按性别)')
三、plotly 交互式可视化
import plotly.express as px
import plotly.graph_objects as go
from plotly.subplots import make_subplots
# 交互散点图
df = px.data.gapminder().query("year == 2007")
fig = px.scatter(df,
x='gdpPercap', y='lifeExp',
size='pop', color='continent',
hover_name='country',
size_max=60,
log_x=True,
title='2007年各国GDP与预期寿命关系',
labels={'gdpPercap': '人均GDP(对数)', 'lifeExp': '预期寿命(年)'})
fig.update_layout(font_family='SimHei')
fig.show()
# 交互时序折线图
df_ts = px.data.stocks()
fig = px.line(df_ts, x='date', y=['GOOG', 'AAPL', 'AMZN'],
title='科技股价格走势对比',
labels={'value': '股价(USD)', 'date': '日期'})
fig.update_xaxes(rangeslider_visible=True) # 添加时间范围滑块
# 组合图表(双Y轴)
fig = make_subplots(rows=2, cols=2,
subplot_titles=['销售趋势', '分类占比', '地区分布', '增长率'])
months = ['1月', '2月', '3月', '4月', '5月', '6月']
sales = [120, 135, 118, 165, 180, 195]
orders = [85, 92, 78, 110, 125, 140]
# 子图1:双轴折线
fig.add_trace(go.Scatter(x=months, y=sales, name='销售额', line_color='#E74C3C'), row=1, col=1)
fig.add_trace(go.Bar(x=months, y=orders, name='订单量', marker_color='#3498DB', opacity=0.7), row=1, col=1)
# 子图2:饼图
labels = ['产品A', '产品B', '产品C', '产品D']
values = [40, 25, 20, 15]
fig.add_trace(go.Pie(labels=labels, values=values, name=''), row=1, col=2)
fig.update_layout(height=700, title_text='业务数据综合仪表板', showlegend=True)
fig.write_html('dashboard.html') # 保存为可分享的HTML文件
fig.show()
四、可视化最佳实践
# 颜色方案选择建议
COLORS = {
'primary': '#3498DB', # 蓝色:主要数据系列
'success': '#27AE60', # 绿色:正向/增长
'danger': '#E74C3C', # 红色:警告/负向
'warning': '#F39C12', # 橙色:注意
'neutral': '#95A5A6', # 灰色:参考/对比
}
# 图表配色方案(适合色盲友好)
PALETTE_COLORBLIND = ['#0072B2', '#E69F00', '#009E73', '#CC79A7', '#56B4E9', '#D55E00']
# 统一图表样式函数
def style_axes(ax, title='', xlabel='', ylabel='', legend=True):
ax.set_title(title, fontsize=14, fontweight='bold', pad=15)
ax.set_xlabel(xlabel, fontsize=11)
ax.set_ylabel(ylabel, fontsize=11)
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
ax.tick_params(labelsize=10)
if legend:
ax.legend(frameon=False)
return ax
五、开发痛点与报错避坑指南
| 问题 |
原因 |
解决方案 |
| 中文乱码/方框 |
未配置中文字体 |
plt.rcParams['font.sans-serif'] = ['SimHei'] |
| 图表在Jupyter外不显示 |
后端配置问题 |
脚本中加 plt.show() 或保存 savefig() |
| seaborn 图形模糊 |
DPI设置低 |
plt.rcParams['figure.dpi'] = 150 |
| plotly 图表太大 |
数据量超大 |
使用 go.Scattergl(WebGL加速)替代 go.Scatter |
| 负号显示为方块 |
负号字符编码 |
plt.rcParams['axes.unicode_minus'] = False |
六、全文总结
| 场景 |
推荐库 |
| 科研论文图表 |
matplotlib(精细控制) |
| 统计分析可视化 |
seaborn(美观快捷) |
| 交互式报告/仪表板 |
plotly(支持HTML导出) |
| 实时数据大屏 |
plotly Dash / Streamlit |
| 超大数据量 |
datashader + plotly |
七、技术进阶展望
- 学习
Streamlit ------ 5分钟将 Python 分析脚本变成 Web 应用
- 探索
Plotly Dash 构建生产级数据仪表板
- 研究
Altair ------ 基于 Vega-Lite 的声明式可视化
参考文献
- matplotlib 官方文档
- seaborn 官方文档
- Plotly Python 官方文档
- matplotlib 中文字体配置指南
- Scientific Visualization: Python + Matplotlib(开源书)