pandas DataFrame如何在已有绘图上叠加工作日分时均值曲线
问题根源
你之前无法合并两条曲线的核心原因是avg_week的索引是「星期序号+当日分钟数」的非时间类型值,和最近7天数据的datetime时间轴量纲不统一,仅手动修改x轴刻度标签无法实现坐标点的一一映射,必然会出现错位。
解决方案
核心思路是不直接绘制多级索引的周均值结果,而是把周均值匹配到最近7天数据的datetime时间轴上,让两个序列共用同一套x轴坐标,即可实现无错位同图绘制,具体实现步骤如下:
- 第一步:预处理时间字段,避免取整逻辑bug
用pandas原生时间取整方法替代手动计算分钟数的逻辑,减少边界错误:
import pandas as pd import datetime import matplotlib.pyplot as plt # 确保date列为datetime格式 df['date'] = pd.to_datetime(df['date']) # 按10分钟向下取整生成时间基准列 df['time_10min_round'] = df['date'].dt.floor('10T') # 提取星期序号(0=周一,6=周日) df['weekday'] = df['date'].dt.weekday # 计算取整后时间距当日零点的分钟数,作为均值分组键 df['day_minute'] = df['time_10min_round'].dt.hour * 60 + df['time_10min_round'].dt.minute
- 第二步:生成周均值映射表
将分组后的周均值转为键值对格式,方便后续快速匹配:
# 计算各工作日各10分钟节点的N均值,转为字典 week_avg_map = df.groupby(['weekday', 'day_minute'])['N'].mean().to_dict()
- 第三步:筛选最近7天数据,匹配对应周均值
保持你原有的最近7天筛选逻辑,给筛选出的每一条数据匹配对应星期、对应时间点的周均值:
# 按原有逻辑计算时间截断点 time_cutoff = df['date'].max() - pd.Timedelta( days=6, minutes=60*datetime.datetime.now().hour + datetime.datetime.now().minute ) # 筛选最近7天数据 df_recent7 = df[df['date'] > time_cutoff].copy() # 匹配周均值 df_recent7['week_avg_N'] = df_recent7.apply( lambda x: week_avg_map.get( (x['weekday'], x['day_minute']) ), axis=1 )
- 第四步:同坐标系绘图
此时两个序列均以datetime类型的date列为x轴,直接调用plot即可自动对齐:
fig, ax = plt.subplots(figsize=(12, 6), dpi=100) # 绘制最近7天实际值 df_recent7.plot( x='date', y='N', ax=ax, label='最近7天实际N值', color='#ff7f0e', alpha=0.8 ) # 绘制周分时均值 df_recent7.plot( x='date', y='week_avg_N', ax=ax, label='工作日分时均值', color='#1f77b4', linewidth=2 ) # 调整x轴样式 ax.tick_params(axis='x', rotation=45, labelsize=9) ax.set_xlabel('日期时间') ax.set_ylabel('N值') ax.legend() plt.tight_layout() plt.show()
方案优点
- 不需要手动计算x轴刻度位置、手动设置标签,matplotlib会自动适配datetime轴的显示格式,不会出现刻度错位
- 周均值和实际值的时间点完全一一对应,比如最近7天里的周五15:00,会自动匹配周五15:00的历史均值,不会出现星期顺序和实际日期不匹配的问题
- 代码逻辑可复用性强,后续如果要调整时间粒度(比如改成5分钟、15分钟均值),只需要修改floor方法的参数即可,不需要重写分组逻辑
内容的提问来源于stack exchange,提问作者Suuuehgi
相关产品推荐
相关产品推荐

