如何正确分离子图并绘制单条时序曲线?解决多线重复问题
问题描述
我有一份包含11列的时序数据表,想用matplotlib的subplots函数绘制子图对比各列数据的时序变化。但运行代码后,每个子图都显示11条重复曲线,曲线梯度也没随时间正常变化,没法实现每个子图仅展示对应列单条时序曲线的需求,参考VAR模型教程也没解决,求正确绘图方法。
示例数据表
(注:完整表共11列,以下为部分列示例)
| Time Period | HR | Legal | Fin | Leadership | Market | UX | CX |
|---|---|---|---|---|---|---|---|
| 01/04/2021 | 6.39 | 5.81 | 7.53 | 7.16 | 6.78 | 7.25 | 7.40 |
| 01/07/2021 | 6.95 | 6.25 | 7.46 | 7.16 | 7.05 | 7.51 | 7.70 |
| 01/10/2021 | 7.41 | 6.43 | 7.65 | 7.50 | 7.25 | 7.74 | 8.00 |
| 01/01/2022 | 7.51 | 6.51 | 7.74 | 7.52 | 8.00 | 7.84 | 8.10 |
| 01/04/2022 | 7.70 | 6.91 | 7.86 | 7.59 | 7.69 | 7.81 | 8.13 |
| 01/07/2022 | 7.80 | 6.60 | 7.50 | 7.50 | 7.80 | 7.50 | 7.70 |
当前使用代码
import pandas as pd from datetime import date, timedelta import datetime import matplotlib.pyplot as plt plt.style.use('fivethirtyeight') from statsmodels.tsa.seasonal import seasonal_decompose from statsmodels.graphics.tsaplots import plot_pacf from statsmodels.tsa.arima_model import ARIMA import statsmodels.api as sm import warnings from plotly.offline import download_plotlyjs, init_notebook_mode, plot from plotly.graph_objs import * init_notebook_mode() # 设置文件路径 inputfilepath = "你的数据文件路径" data = pd.read_csv(inputfilepath, parse_dates=["Time Period"], index_col = "Time Period") print(data.shape) # 转换列为datetime格式(已通过read_csv的parse_dates参数处理,此处注释) #data["Time Period"] = pd.to_datetime(data['Time Period'], format="%d/%m/%Y") fig, axes = plt.subplots(nrows=3, ncols=4, dpi=110, figsize=(10,6)) for i, ax in enumerate(axes.flatten()): macro_data = data[data.columns[i]] ax.plot(data, color='red', linewidth=1) # 装饰设置 ax.set_title(data.columns[i], fontsize = 10) ax.xaxis.set_ticks_position('none') ax.yaxis.set_ticks_position('none') ax.spines["top"].set_alpha(0) ax.tick_params(labelsize=6) plt.tight_layout();
错误效果与期望效果
- 错误效果:每个子图都绘制了所有11列的曲线,无法区分单条时序变化
- 期望效果:每个子图仅展示对应列的单条时序曲线,清晰对比各列趋势
解决方法
错误原因
循环中ax.plot(data)会把整个DataFrame的所有列都绘制到当前子图中,这就是每个子图出现11条曲线的根本原因。另外,3行4列的子图布局会生成12个轴对象,而我们只有11列数据,最后一个空轴需要隐藏。
修正后的代码
import pandas as pd import matplotlib.pyplot as plt plt.style.use('fivethirtyeight') # 设置文件路径 inputfilepath = "你的数据文件路径" data = pd.read_csv(inputfilepath, parse_dates=["Time Period"], index_col = "Time Period") print(data.shape) fig, axes = plt.subplots(nrows=3, ncols=4, dpi=110, figsize=(10,6)) # 遍历前11个轴对象(对应11列数据) for i, ax in enumerate(axes.flatten()[:len(data.columns)]): # 提取当前列的数据 current_col_data = data.iloc[:, i] # 仅绘制当前列的时序曲线 ax.plot(current_col_data, color='red', linewidth=1) # 装饰设置 ax.set_title(data.columns[i], fontsize = 10) ax.xaxis.set_ticks_position('none') ax.yaxis.set_ticks_position('none') ax.spines["top"].set_alpha(0) ax.tick_params(labelsize=6) # 旋转x轴标签避免重叠 plt.setp(ax.get_xticklabels(), rotation=45, ha='right') # 隐藏第12个多余的子图 axes.flatten()[-1].axis('off') plt.tight_layout() plt.show()
关键修改点
- 绘图数据修正:把
ax.plot(data)改为绘制提取的单列数据current_col_data,确保每个子图只显示对应列的曲线 - 子图数量匹配:通过
axes.flatten()[:len(data.columns)]只遍历与数据列数对应的子图,最后一个空轴用axis('off')隐藏 - 优化x轴标签:添加
plt.setp(ax.get_xticklabels(), rotation=45, ha='right')避免时间标签重叠
内容的提问来源于stack exchange,提问作者Scythor
相关产品推荐
相关产品推荐

