如何绘制进程时长可视化图,展示日期、起止时间及小时轴?
进程时长可视化问题解决方案
问题背景
现有如下结构的进程时序DataFrame:
| variable | year | start | end | seconds | hours | start_time | start_date |
|---|---|---|---|---|---|---|---|
| 10m_u_component_of_wind | 2005 | 2005 | 2022-04-25 13:14:45 | 2022-04-26 02:13:56 | 46751 | 12.986389 | 13:14 |
| 10m_u_component_of_wind | 2006 | 2006 | 2022-04-26 04:56:26 | 2022-04-26 14:56:35 | 36009 | 10.002500 | 04:56 |
| 10m_u_component_of_wind | 2007 | 2007 | 2022-04-26 05:01:04 | 2022-04-26 20:45:38 | 56674 | 15.742778 | 05:01 |
| .. | .. | .. | .. | .. | .. | .. | .. |
尝试使用seaborn.stripplot绘制可视化时遇到问题:注释ax.set_ylim(["00:00", "23:59"])后无数据显示,不注释则Y轴无法覆盖完整时间范围。需求是实现展示开始日期、水平方向进程时长、Y轴开始时间,同时突出早于08:30或晚于17:30启动的进程。
解决方案与替代思路
1. 核心数据预处理
首先需要将字符串格式的开始时间转换为数值类型(小时数,0-24),同时标记异常时段进程:
import pandas as pd import matplotlib.pyplot as plt import seaborn as sns # 转换开始时间为datetime格式,再提取小时数值 timings['start_time_dt'] = pd.to_datetime(timings['start_time'], format='%H:%M') timings['start_hour'] = timings['start_time_dt'].dt.hour + timings['start_time_dt'].dt.minute/60 # 标记早于08:30或晚于17:30的进程 timings['is_off_hours'] = ((timings['start_hour'] < 8.5) | (timings['start_hour'] > 17.5))
2. 推荐可视化:水平分组条形图(最优时长展示)
水平条形图最适合直观比较进程时长,配合日期分组和异常标记,完全满足需求:
cm = 1 / 2.54 # 按日期分组绘制水平条形图 g = sns.catplot( data=timings, x='hours', y='start_hour', hue='is_off_hours', col='start_date', kind='bar', orient='h', height=8, aspect=1.5 ) # 自定义Y轴刻度为时间格式 yticks = [0, 4, 8, 8.5, 12, 17.5, 20, 23] yticklabels = ['00:00', '04:00', '08:00', '08:30', '12:00', '17:30', '20:00', '23:59'] for ax in g.axes.flat: ax.set_yticks(yticks) ax.set_yticklabels(yticklabels) ax.set_ylim(0, 24) # 添加红色虚线标记正常时段边界 ax.axhline(y=8.5, color='red', linestyle='--') ax.axhline(y=17.5, color='red', linestyle='--') # 设置标题与标签 g.fig.suptitle('Duration of processes', y=1.05) g.set_titles('Start Date: {col_name}') g.set_xlabels('Process Duration (hours)') g.set_ylabels('Start Time') plt.legend(title='Off Hours', labels=['No', 'Yes']) plt.show()
3. 修复原Stripplot方案
如果坚持使用散点类图,需修正Y轴数据类型问题:
cm = 1 / 2.54 figure, ax = plt.subplots(figsize=(50*cm, 20*cm)) # 使用数值类型的start_hour作为Y轴 plot = sns.stripplot( data=timings, x='start_date', y='start_hour', hue='is_off_hours', size=10, jitter=True ) # 配置Y轴范围与刻度 ax.set_ylim(0, 24) ax.set_yticks(yticks) ax.set_yticklabels(yticklabels) # 添加时段边界标记 ax.axhline(y=8.5, color='red', linestyle='--') ax.axhline(y=17.5, color='red', linestyle='--') # 设置标题与标签 plt.suptitle('Duration of processes') plt.title('using patching script (commit fb14897574f55915bfc65d8be23e6242c7bdbb99)') plt.legend(title='Off Hours', labels=['No', 'Yes']) plt.xlabel('Start Date') plt.ylabel('Start Time') plt.show()
关键说明
- 字符串格式的时间无法被Matplotlib识别为连续轴,必须转换为数值类型(小时数)才能正确处理排序与范围。
- 水平条形图是展示时长的最优选择,长度对比远优于散点的位置对比。
- 通过
is_off_hours标记+颜色区分,可快速识别异常时段启动的进程。
内容的提问来源于stack exchange,提问作者Nikos Alexandris
相关产品推荐
相关产品推荐

