数据可视化
目录
基础绘图
Pandas 使用 Matplotlib 作为绘图后端,可以通过 plot() 方法快速绘图。
python
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
# 确保图表在 Jupyter 中显示
# %matplotlib inline
# 创建示例数据
dates = pd.date_range('2024-01-01', periods=100, freq='D')
df = pd.DataFrame({
'值': np.random.randn(100).cumsum()
}, index=dates)
# 基础绘图
df.plot()
plt.show()
折线图
python
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
# 创建时间序列数据
dates = pd.date_range('2024-01-01', periods=50, freq='D')
df = pd.DataFrame({
'股票A': 100 + np.random.randn(50).cumsum(),
'股票B': 100 + np.random.randn(50).cumsum(),
'股票C': 100 + np.random.randn(50).cumsum()
}, index=dates)
# 折线图
df.plot(kind='line', figsize=(10, 6))
plt.title('股票价格走势')
plt.xlabel('日期')
plt.ylabel('价格')
plt.grid(True)
plt.legend()
plt.show()
# 只绘制特定列
df[['股票A', '股票B']].plot()
plt.show()
柱状图
python
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
data = {
'产品': ['A', 'B', 'C', 'D', 'E'],
'销售额': [1000, 1500, 1200, 1800, 900],
'利润': [200, 300, 250, 350, 150]
}
df = pd.DataFrame(data)
# 垂直柱状图
df.plot(x='产品', y='销售额', kind='bar', figsize=(8, 6))
plt.title('产品销售')
plt.ylabel('销售额')
plt.show()
# 水平柱状图
df.plot(x='产品', y='销售额', kind='barh')
plt.show()
# 分组柱状图
df.plot(x='产品', y=['销售额', '利润'], kind='bar')
plt.show()
# 堆叠柱状图
df.plot(x='产品', y=['销售额', '利润'], kind='bar', stacked=True)
plt.show()
散点图
python
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
np.random.seed(42)
df = pd.DataFrame({
'X': np.random.randn(100),
'Y': np.random.randn(100),
'类别': np.random.choice(['A', 'B', 'C'], 100)
})
# 散点图
df.plot(x='X', y='Y', kind='scatter', figsize=(8, 6))
plt.title('散点图')
plt.show()
# 使用不同颜色表示类别
for category in df['类别'].unique():
subset = df[df['类别'] == category]
plt.scatter(subset['X'], subset['Y'], label=category)
plt.legend()
plt.show()
直方图
python
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
# 创建数据
df = pd.DataFrame({
'数值': np.random.normal(100, 15, 1000)
})
# 直方图
df['数值'].plot(kind='hist', bins=30, figsize=(8, 6))
plt.title('数值分布直方图')
plt.xlabel('数值')
plt.ylabel('频数')
plt.show()
# 密度图
df['数值'].plot(kind='density', figsize=(8, 6))
plt.title('数值分布密度图')
plt.show()
# 多个直方图
df2 = pd.DataFrame({
'组A': np.random.normal(100, 15, 1000),
'组B': np.random.normal(120, 20, 1000)
})
df2.plot(kind='hist', bins=30, alpha=0.7, figsize=(8, 6))
plt.show()
箱线图
python
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
df = pd.DataFrame({
'组A': np.random.normal(100, 15, 100),
'组B': np.random.normal(120, 20, 100),
'组C': np.random.normal(110, 18, 100)
})
# 箱线图
df.plot(kind='box', figsize=(8, 6))
plt.title('箱线图')
plt.ylabel('数值')
plt.show()
# 垂直箱线图
df.boxplot(figsize=(8, 6))
plt.show()
其他图表类型
面积图
python
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
dates = pd.date_range('2024-01-01', periods=30, freq='D')
df = pd.DataFrame({
'系列A': np.random.randn(30).cumsum(),
'系列B': np.random.randn(30).cumsum()
}, index=dates)
# 面积图
df.plot(kind='area', figsize=(10, 6), alpha=0.7)
plt.title('面积图')
plt.show()
饼图
python
import pandas as pd
import matplotlib.pyplot as plt
data = {
'类别': ['A', 'B', 'C', 'D'],
'数值': [30, 25, 20, 25]
}
df = pd.DataFrame(data)
# 饼图
df.plot(x='类别', y='数值', kind='pie', autopct='%1.1f%%', figsize=(8, 8))
plt.ylabel('')
plt.title('饼图')
plt.show()
# 使用 Series
s = pd.Series([30, 25, 20, 25], index=['A', 'B', 'C', 'D'])
s.plot(kind='pie', autopct='%1.1f%%')
plt.show()
图表自定义
基本自定义
python
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
dates = pd.date_range('2024-01-01', periods=50, freq='D')
df = pd.DataFrame({
'值': np.random.randn(50).cumsum()
}, index=dates)
ax = df.plot(figsize=(12, 6),
title='自定义图表',
color='red',
linestyle='--',
linewidth=2,
marker='o',
markersize=4)
ax.set_xlabel('日期', fontsize=12)
ax.set_ylabel('数值', fontsize=12)
ax.grid(True, alpha=0.3)
ax.legend(['数据系列'], fontsize=10)
plt.tight_layout()
plt.show()
多子图
python
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
dates = pd.date_range('2024-01-01', periods=50, freq='D')
df = pd.DataFrame({
'系列A': np.random.randn(50).cumsum(),
'系列B': np.random.randn(50).cumsum(),
'系列C': np.random.randn(50).cumsum()
}, index=dates)
# 创建子图
fig, axes = plt.subplots(2, 2, figsize=(12, 10))
# 在子图上绘图
df['系列A'].plot(ax=axes[0, 0], title='系列A')
df['系列B'].plot(ax=axes[0, 1], title='系列B')
df['系列C'].plot(ax=axes[1, 0], title='系列C')
df.plot(ax=axes[1, 1], title='所有系列')
plt.tight_layout()
plt.show()
实际应用示例
示例 1:股票数据分析可视化
python
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
# 创建股票数据
np.random.seed(42)
dates = pd.date_range('2024-01-01', periods=100, freq='D')
stock_prices = 100 * np.cumprod(1 + np.random.randn(100) * 0.02)
df = pd.DataFrame({
'收盘价': stock_prices,
'成交量': np.random.randint(1000000, 5000000, 100)
}, index=dates)
# 计算移动平均
df['5日均线'] = df['收盘价'].rolling(window=5).mean()
df['20日均线'] = df['收盘价'].rolling(window=20).mean()
# 创建双轴图
fig, ax1 = plt.subplots(figsize=(12, 6))
# 左轴:价格
ax1.set_xlabel('日期')
ax1.set_ylabel('价格', color='black')
ax1.plot(df.index, df['收盘价'], label='收盘价', color='blue')
ax1.plot(df.index, df['5日均线'], label='5日均线', color='orange')
ax1.plot(df.index, df['20日均线'], label='20日均线', color='green')
ax1.tick_params(axis='y', labelcolor='black')
ax1.legend(loc='upper left')
ax1.grid(True, alpha=0.3)
# 右轴:成交量
ax2 = ax1.twinx()
ax2.set_ylabel('成交量', color='gray')
ax2.bar(df.index, df['成交量'], alpha=0.3, color='gray')
ax2.tick_params(axis='y', labelcolor='gray')
plt.title('股票价格和成交量分析')
plt.tight_layout()
plt.show()
示例 2:销售数据可视化
python
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
# 创建销售数据
np.random.seed(42)
months = pd.date_range('2024-01-01', periods=12, freq='M')
sales = pd.DataFrame({
'产品A': np.random.randint(1000, 5000, 12),
'产品B': np.random.randint(1500, 6000, 12),
'产品C': np.random.randint(800, 4000, 12)
}, index=months)
# 创建多个图表
fig, axes = plt.subplots(2, 2, figsize=(14, 10))
# 1. 月度销售额趋势
sales.plot(ax=axes[0, 0], title='月度销售额趋势', marker='o')
axes[0, 0].set_xlabel('月份')
axes[0, 0].set_ylabel('销售额')
axes[0, 0].legend()
# 2. 柱状图
sales.sum().plot(kind='bar', ax=axes[0, 1], title='年度总销售额')
axes[0, 1].set_xlabel('产品')
axes[0, 1].set_ylabel('总销售额')
axes[0, 1].tick_params(axis='x', rotation=45)
# 3. 堆叠面积图
sales.plot(kind='area', ax=axes[1, 0], title='销售额堆叠', alpha=0.7)
axes[1, 0].set_xlabel('月份')
axes[1, 0].set_ylabel('销售额')
axes[1, 0].legend()
# 4. 饼图(年度总计)
sales.sum().plot(kind='pie', ax=axes[1, 1], autopct='%1.1f%%', title='产品销售占比')
axes[1, 1].set_ylabel('')
plt.tight_layout()
plt.show()
总结
Pandas 提供了便捷的数据可视化功能:
- plot() 方法:快速绘图
- 多种图表类型:折线图、柱状图、散点图、直方图、箱线图等
- 图表自定义:颜色、样式、标签等
- 多子图:在一个图中显示多个图表
- 双轴图:显示不同量纲的数据