seaborn时间分组计数热力图 如何调整聚合时间粒度并将时间置于X轴
按自定义时间粒度绘制时间热力图的实现方案
现存问题
原有实现按小时+分钟的最细粒度拆分统计,时间粒度过细导致单个时间块的计数值偏低,生成的热力图不具备实际参考价值。
调整目标
- 支持自定义时间块聚合粒度,可灵活切换测试5分钟、10分钟等不同聚合时长的效果
- 调整时间维度排布在X轴,最终效果匹配参考示意图
原有代码的问题修正
- 修复时间格式化字符串笔误(原代码
%H:%M%:%S存在多余的冒号) - 补充缺失的依赖导入(原代码调用
np但未导入numpy库) - 替换硬拆小时、分钟字段的分组逻辑,改为可配置的时间分桶聚合
核心实现逻辑
- 采用
pd.Grouper基于时间列按设定时长自动分桶,仅需修改参数即可切换聚合粒度,无需手动调整分桶规则 - 对聚合结果矩阵做转置处理,将时间维度设为DataFrame的列索引,最终在热力图上排布到X轴,匹配参考图布局
可直接运行的完整代码
import numpy as np import seaborn as sns import pandas as pd import matplotlib.pyplot as plt from datetime import datetime, timedelta # 核心可配置参数:修改此值即可切换5/10/15分钟等不同聚合粒度 time_bucket_minutes = 5 start = datetime(1900,1,1,10,0,0) end = datetime(1900,1,1,13,0,0) seconds = (end - start).total_seconds() step = timedelta(minutes=1) array = [] for i in range(0, int(seconds), int(step.total_seconds())): array.append(start + timedelta(seconds=i)) # 修正原代码的时间格式化笔误 array = [i.strftime('%Y-%m-%d %H:%M:%S') for i in array] df2 = pd.DataFrame(array).rename(columns={0:'Time'}) df2['Count'] = np.random.uniform(0.0, 0.5, size=len(df2)) df2['Count'] = df2['Count'].round(1) df2['Time'] = pd.to_datetime(df2['Time']) # 按自定义时间粒度分桶统计不同Count值的出现频次 agg_df = df2.groupby( [pd.Grouper(key='Time', freq=f'{time_bucket_minutes}min'), 'Count'] ).size().unstack(fill_value=0) # 转置矩阵,将时间维度调整到X轴 agg_df = agg_df.T # 格式化X轴的时间标签为易读的HH:MM格式 agg_df.columns = agg_df.columns.strftime('%H:%M') # 绘制热力图 sns.heatmap(agg_df) plt.xlabel('聚合时间块') plt.ylabel('统计变量取值') plt.tight_layout() plt.show()
使用说明
- 若需要测试10分钟聚合效果,只需将
time_bucket_minutes的值修改为10即可,其余代码无需变动 - 可通过调整热力图色阶、坐标轴标签样式,进一步匹配参考图的视觉效果
内容的提问来源于stack exchange,提问作者Chopin
相关产品推荐
相关产品推荐

