Pandas 是 Python 数据分析的核心库,它内置了基于 Matplotlib 的绘图功能,可以让你从 DataFrame 或 Series 中快速创建图表。 结合 Pandas 的便捷性和 Matplotlib 的灵活性,你可以高效地进行数据探索和可视化定制。
Pandas 通过 DataFrame.plot() 和 Series.plot() 方法提供绘图接口,本质上是 Matplotlib pyplot 的封装。默认绘制折线图:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# 创建一个示例DataFrame
df = pd.DataFrame({
'A': np.random.randn(100).cumsum(),
'B': np.random.randn(100).cumsum(),
'C': np.random.randn(100).cumsum()
})
df.plot() # 直接绘制折线图
plt.title('Pandas默认折线图')
plt.show()
kind 参数支持多种图表类型:
'line' : 折线图(默认)'bar' : 垂直条形图'barh' : 水平条形图'hist' : 直方图'box' : 箱线图'kde' 或 'density' : 核密度估计图'area' : 面积图'pie' : 饼图(针对Series)'scatter' : 散点图(需要指定x和y)'hexbin' : 六边形箱图# 创建分类数据
df_bar = pd.DataFrame({
'销售额': [35, 28, 42, 30],
'利润': [8, 5, 12, 7]
}, index=['产品A', '产品B', '产品C', '产品D'])
df_bar.plot(kind='bar', figsize=(8,5))
plt.title('产品销售额与利润')
plt.ylabel('金额 (万元)')
plt.show()
对于散点图,需要指定 x 和 y 列的名称:
df_scatter = pd.DataFrame({
'height': np.random.normal(170, 10, 200),
'weight': np.random.normal(65, 15, 200)
})
df_scatter.plot(kind='scatter', x='height', y='weight', alpha=0.6)
plt.title('身高体重分布')
plt.show()
df_hist = pd.DataFrame({
'年龄': np.random.randint(18, 65, 500),
'收入': np.random.randn(500) * 20 + 50
})
df_hist['年龄'].plot(kind='hist', bins=20, edgecolor='black', alpha=0.7)
plt.title('年龄分布直方图')
plt.show()
# 密度图
df_hist['收入'].plot(kind='kde', linewidth=2)
plt.title('收入密度曲线')
plt.show()
可以直接对整个DataFrame绘制箱线图:
df_box = pd.DataFrame({
'组A': np.random.randn(100),
'组B': np.random.randn(100) + 1,
'组C': np.random.randn(100) * 1.5
})
df_box.plot(kind='box')
plt.title('多组箱线图')
plt.show()
Pandas 对时间索引有特殊支持,绘图时会自动处理时间轴格式:
# 创建时间序列
dates = pd.date_range('2023-01-01', periods=100, freq='D')
ts = pd.Series(np.random.randn(100).cumsum(), index=dates)
ts.plot(figsize=(10,5))
plt.title('时间序列累积值')
plt.xlabel('日期')
plt.ylabel('值')
plt.grid(True)
plt.show()
DataFrame 有多列时,默认会绘制多条曲线,并自动添加图例:
df_multi = pd.DataFrame(np.random.randn(100, 3).cumsum(axis=0),
columns=['指标X', '指标Y', '指标Z'])
df_multi.plot()
plt.title('多指标趋势')
plt.show()
结合 groupby 可以绘制分组后的统计图:
# 创建包含分组的数据
df_group = pd.DataFrame({
'类别': np.random.choice(['A', 'B', 'C'], 200),
'数值': np.random.randn(200)
})
# 分组后绘制箱线图
df_group.boxplot(column='数值', by='类别')
plt.suptitle('') # 去掉自动添加的标题
plt.title('按类别分组的数值分布')
plt.show()
# 分组聚合后绘制条形图
df_group.groupby('类别')['数值'].mean().plot(kind='bar')
plt.title('各类别均值')
plt.show()
Pandas 绘图方法返回 Axes 对象(或数组),可以继续使用 Matplotlib 进行精细调整:
ax = df.plot(figsize=(10,5), style=['b-','r--','g:']) # 自定义线型
ax.set_title('定制化图表', fontsize=14, color='navy')
ax.set_xlabel('索引')
ax.set_ylabel('值')
ax.legend(['A线','B线','C线'])
ax.grid(True, linestyle=':', alpha=0.6)
plt.show()
通过 subplots=True 可以将各列分别绘制在单独的子图中:
df.plot(subplots=True, figsize=(10,8), layout=(3,1), sharex=True)
plt.tight_layout()
plt.show()
layout 可以指定子图的行列排列。通过获取 figure 对象或使用 plt.savefig:
ax = df.plot()
fig = ax.get_figure()
fig.savefig('pandas_plot.png', dpi=300, bbox_inches='tight')
# 或者直接使用 plt
plt.savefig('pandas_plot_v2.png', dpi=300)
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
# 生成模拟销售数据
np.random.seed(42)
dates = pd.date_range('2023-01-01', periods=365, freq='D')
sales = pd.DataFrame({
'日期': dates,
'销售额': np.random.poisson(200, 365) + np.sin(np.arange(365)/30)*50 + 50,
'地区': np.random.choice(['北区','南区','东区','西区'], 365)
})
# 按周重采样,分析周度趋势
sales.set_index('日期', inplace=True)
weekly = sales['销售额'].resample('W').sum()
# 创建图形
fig, axes = plt.subplots(2, 2, figsize=(14, 10))
# 子图1:日度销售额折线图(平滑处理)
sales['销售额'].rolling(7).mean().plot(ax=axes[0,0], color='blue', linewidth=2)
axes[0,0].set_title('日度销售额(7日移动平均)')
axes[0,0].set_ylabel('销售额')
# 子图2:周度销售额柱状图
weekly.plot(kind='bar', ax=axes[0,1], color='green', alpha=0.7)
axes[0,1].set_title('周度销售额')
axes[0,1].set_ylabel('销售额')
axes[0,1].tick_params(axis='x', rotation=45)
# 子图3:各地区销售额箱线图
sales.boxplot(column='销售额', by='地区', ax=axes[1,0])
axes[1,0].set_title('各地区销售额分布')
axes[1,0].set_ylabel('销售额')
axes[1,0].set_xlabel('地区')
# 子图4:销售额分布直方图
sales['销售额'].plot(kind='hist', bins=30, ax=axes[1,1], edgecolor='black', alpha=0.7)
axes[1,1].set_title('销售额分布直方图')
axes[1,1].set_xlabel('销售额')
plt.suptitle('销售数据分析仪表板', fontsize=16)
plt.tight_layout()
plt.savefig('sales_dashboard.png', dpi=300)
plt.show()
Pandas 官方文档提供了更详细的绘图指南:Pandas Visualization
Pandas + Matplotlib 是数据分析的黄金组合。掌握本章技巧后,你可以快速从数据中洞察信息,并生成高质量的图表。下一章将介绍如何自定义颜色和样式,让你的图表更加专业。