数据可视化 #
可视化概述 #
Pandas 集成了 Matplotlib,提供了便捷的绘图接口,可以快速创建常用图表。
text
┌─────────────────────────────────────────────────────────────┐
│ Pandas 绘图类型 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 基础图表 │
│ ├── plot.line() 折线图 │
│ ├── plot.bar() 柱状图 │
│ ├── plot.barh() 横向柱状图 │
│ ├── plot.hist() 直方图 │
│ └── plot.box() 箱线图 │
│ │
│ 统计图表 │
│ ├── plot.kde() 核密度估计 │
│ ├── plot.area() 面积图 │
│ ├── plot.pie() 饼图 │
│ └── plot.scatter() 散点图 │
│ │
│ 高级图表 │
│ ├── plot.hexbin() 六边形图 │
│ └── scatter_matrix() 散点图矩阵 │
│ │
└─────────────────────────────────────────────────────────────┘
准备环境 #
python
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# 设置中文字体
plt.rcParams['font.sans-serif'] = ['Arial Unicode MS'] # macOS
plt.rcParams['axes.unicode_minus'] = False
# 设置图表风格
plt.style.use('seaborn-v0_8-whitegrid')
# 准备数据
np.random.seed(42)
df = pd.DataFrame({
'A': np.random.randn(100).cumsum(),
'B': np.random.randn(100).cumsum(),
'C': np.random.randn(100).cumsum()
}, index=pd.date_range('2024-01-01', periods=100))
折线图 #
python
# 基本折线图
df.plot()
plt.title('Line Plot')
plt.show()
# 单列
df['A'].plot()
# 指定样式
df.plot(style=['-', '--', ':'])
df.plot(linewidth=2, figsize=(10, 6))
# 带标记点
df.plot(marker='o', markersize=3)
# 子图
df.plot(subplots=True, figsize=(10, 8))
df.plot(subplots=True, layout=(1, 3), figsize=(15, 4))
柱状图 #
python
# 准备数据
df_bar = pd.DataFrame({
'category': ['A', 'B', 'C', 'D'],
'value1': [10, 20, 15, 25],
'value2': [15, 25, 20, 30]
})
# 垂直柱状图
df_bar.plot(x='category', y='value1', kind='bar')
# 或
df_bar.plot.bar(x='category', y='value1')
# 多列柱状图
df_bar.plot.bar(x='category', y=['value1', 'value2'])
# 堆叠柱状图
df_bar.plot.bar(x='category', stacked=True)
# 水平柱状图
df_bar.plot.barh(x='category', y=['value1', 'value2'])
# 自定义颜色
df_bar.plot.bar(x='category', color=['skyblue', 'salmon'])
直方图 #
python
# 准备数据
df_hist = pd.DataFrame({
'normal': np.random.randn(1000),
'gamma': np.random.gamma(2, 2, 1000)
})
# 基本直方图
df_hist['normal'].plot.hist()
# 多列
df_hist.plot.hist(alpha=0.5) # 半透明
# 指定箱数
df_hist.plot.hist(bins=50)
# 堆叠直方图
df_hist.plot.hist(stacked=True, bins=30)
# 子图
df_hist.plot.hist(subplots=True, bins=30, figsize=(10, 4))
# 概率密度
df_hist['normal'].plot.hist(density=True)
df_hist['normal'].plot.kde() # 核密度估计
箱线图 #
python
# 准备数据
df_box = pd.DataFrame({
'A': np.random.normal(0, 1, 100),
'B': np.random.normal(1, 1.5, 100),
'C': np.random.normal(-1, 0.5, 100)
})
# 基本箱线图
df_box.plot.box()
# 分组箱线图
df_box.plot.box(by='group') # 如果有分组列
# 自定义样式
df_box.plot.box(
color='blue',
vert=True, # 垂直
patch_artist=True, # 填充颜色
showfliers=True # 显示异常值
)
散点图 #
python
# 准备数据
df_scatter = pd.DataFrame({
'x': np.random.randn(100),
'y': np.random.randn(100),
'size': np.random.rand(100) * 100,
'color': np.random.rand(100)
})
# 基本散点图
df_scatter.plot.scatter(x='x', y='y')
# 指定颜色
df_scatter.plot.scatter(x='x', y='y', c='color', colormap='viridis')
# 指定点大小
df_scatter.plot.scatter(x='x', y='y', s='size')
# 自定义样式
df_scatter.plot.scatter(
x='x', y='y',
c='red',
s=50,
alpha=0.5,
edgecolors='black'
)
饼图 #
python
# 准备数据
df_pie = pd.DataFrame({
'category': ['A', 'B', 'C', 'D'],
'value': [30, 25, 20, 25]
})
# 基本饼图
df_pie.plot.pie(y='value', labels=df_pie['category'])
# 自定义样式
df_pie.plot.pie(
y='value',
labels=df_pie['category'],
autopct='%1.1f%%',
startangle=90,
colors=['skyblue', 'salmon', 'lightgreen', 'gold']
)
# 多列饼图
df_pie.set_index('category')['value'].plot.pie()
面积图 #
python
# 准备数据
df_area = pd.DataFrame({
'A': np.random.randn(100).cumsum() + 100,
'B': np.random.randn(100).cumsum() + 100
})
# 基本面积图
df_area.plot.area()
# 堆叠面积图
df_area.plot.area(stacked=True)
# 不堆叠
df_area.plot.area(stacked=False, alpha=0.5)
核密度估计 #
python
# 基本核密度估计
df_hist['normal'].plot.kde()
# 多列
df_hist.plot.kde()
# 指定带宽
df_hist['normal'].plot.kde(bw_method=0.5)
六边形图 #
python
# 大数据散点图
n = 10000
df_hex = pd.DataFrame({
'x': np.random.randn(n),
'y': np.random.randn(n)
})
# 六边形图
df_hex.plot.hexbin(x='x', y='y', gridsize=20)
# 指定聚合函数
df_hex.plot.hexbin(x='x', y='y', gridsize=20, reduce_C_function=np.mean)
散点图矩阵 #
python
from pandas.plotting import scatter_matrix
# 散点图矩阵
df_scatter = pd.DataFrame(np.random.randn(100, 4), columns=['A', 'B', 'C', 'D'])
scatter_matrix(df_scatter, figsize=(10, 10), diagonal='kde')
plt.show()
自定义图表 #
标题和标签 #
python
ax = df.plot()
ax.set_title('My Plot')
ax.set_xlabel('X Axis')
ax.set_ylabel('Y Axis')
ax.legend(['Series A', 'Series B', 'Series C'])
图例 #
python
ax = df.plot()
ax.legend(loc='upper left')
ax.legend(loc='best') # 自动选择最佳位置
ax.legend(bbox_to_anchor=(1.05, 1), loc='upper left') # 图例在外部
网格 #
python
ax = df.plot()
ax.grid(True)
ax.grid(True, linestyle='--', alpha=0.5)
坐标轴范围 #
python
ax = df.plot()
ax.set_xlim(0, 50)
ax.set_ylim(-5, 5)
双 Y 轴 #
python
fig, ax1 = plt.subplots()
ax1.set_xlabel('X Axis')
ax1.set_ylabel('Y1', color='tab:blue')
df['A'].plot(ax=ax1, color='tab:blue')
ax1.tick_params(axis='y', labelcolor='tab:blue')
ax2 = ax1.twinx()
ax2.set_ylabel('Y2', color='tab:red')
df['B'].plot(ax=ax2, color='tab:red')
ax2.tick_params(axis='y', labelcolor='tab:red')
plt.show()
注释 #
python
ax = df['A'].plot()
# 添加文本
ax.text(10, 2, 'Important Point', fontsize=12)
# 添加箭头
ax.annotate('Peak', xy=(20, 3), xytext=(30, 4),
arrowprops=dict(facecolor='black', shrink=0.05))
保存图表 #
python
# 保存为文件
fig = df.plot().get_figure()
fig.savefig('plot.png')
fig.savefig('plot.pdf')
fig.savefig('plot.svg')
# 指定分辨率
fig.savefig('plot.png', dpi=300)
# 指定大小
fig.savefig('plot.png', figsize=(10, 6))
绘图风格 #
python
# 查看可用风格
print(plt.style.available)
# 使用风格
plt.style.use('ggplot')
plt.style.use('seaborn-v0_8')
plt.style.use('dark_background')
# 临时使用
with plt.style.context('ggplot'):
df.plot()
plt.show()
实用案例 #
python
# 多图表组合
fig, axes = plt.subplots(2, 2, figsize=(12, 10))
# 折线图
df['A'].plot(ax=axes[0, 0], title='Line Plot')
# 柱状图
df.head(10).plot.bar(ax=axes[0, 1], title='Bar Plot')
# 直方图
df['A'].plot.hist(ax=axes[1, 0], title='Histogram', bins=30)
# 箱线图
df.plot.box(ax=axes[1, 1], title='Box Plot')
plt.tight_layout()
plt.show()
下一步 #
掌握了数据可视化后,接下来学习 性能优化,了解如何提升 Pandas 的运行效率!
最后更新:2026-04-04