python - 使用 matplotlib 和 pandas 用虚线创建事件的时间图
问题描述
我正在尝试创建一个虚线图,代表我的每个散列的事件长度。我的数据框如下:
hash event start end
0174FAA018E7FAE1E84469ADC34EF666 baseball 00:00:00:000 00:00:00:500
0174FAA018E7FAE1E84469ADC34EF666 baseball 00:00:01:000 00:00:01:500
0174FAA018E7FAE1E84469ADC34EF666 cat 00:00:01:500 00:00:02:500
AF4BB75F98579B8C9F95EABEC1BDD988 baseball 00:00:01:000 00:00:01:500
AF4BB75F98579B8C9F95EABEC1BDD988 cat 00:00:01:500 00:00:02:500
AF4BB75F98579B8C9F95EABEC1BDD988 cat 00:00:03:200 00:00:05:250
AF4BB75F98579B8C9F95EABEC1BDD988 cat 00:00:03:000 00:00:04:350
类似于这里的答案:在 matplotlib 中更改虚线中的破折号间距, 其中哈希位于 y 轴上,x 轴上有时间间隔,事件类型为颜色编码,如果没有,则由空格分解该时间间隔的事件。
这是我迄今为止尝试过的,但它不起作用:
fig,ax = plt.subplots()
ax.plot([0, df.end], [df.hash], linestyle='--', dashes=(5, 5))
例如见下文
解决方案
首先我想说:我与您的请求的第一个关联是 matplotlib 的broken_barh
函数。但到目前为止,我无法弄清楚如何绘制时间增量,因为这在那里是必要的。你的情节也可以完成plot
,所以我有一些带有if False: (attempt with plt.broken_barh) else (plt.plot-version)
结构的代码。见自己。一旦我知道如何在 matplotlib 中绘制 timedeltas,
我将尝试更新字面上损坏的部分...
这是我希望可以帮助你的代码:
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from io import StringIO
def brk_str(s): # just for nicer labeling with such long hashes
return '\n'.join([s[8*i:8*(i+1)] for i in range(4)])
s = ''' hash event start end
0174FAA018E7FAE1E84469ADC34EF666 baseball 00:00:00:000 00:00:00:500
0174FAA018E7FAE1E84469ADC34EF666 baseball 00:00:01:000 00:00:01:500
0174FAA018E7FAE1E84469ADC34EF666 cat 00:00:01:500 00:00:02:500
AF4BB75F98579B8C9F95EABEC1BDD988 baseball 00:00:01:000 00:00:01:500
AF4BB75F98579B8C9F95EABEC1BDD988 cat 00:00:01:500 00:00:02:500
AF4BB75F98579B8C9F95EABEC1BDD988 cat 00:00:03:200 00:00:05:250
AF4BB75F98579B8C9F95EABEC1BDD988 cat 00:00:03:000 00:00:04:350'''
df = pd.read_table(StringIO(s), sep='\s+')
df['start'] = pd.to_datetime(df['start'], format='%H:%M:%S:%f')
df['end'] = pd.to_datetime(df['end'], format='%H:%M:%S:%f')
df['dur'] = (df['end'] - df['start']) # this is only needed in case of broken_barh would work...
e_grpd = df.groupby('event')
fig, ax = plt.subplots()
for i, (e, ev) in enumerate(e_grpd): # iterate over all events, providing a counter i, the name of every event e and its data ev
last_color = None # setting color value to None which means automatically cycle to another color
for k, (h, hv)in enumerate(ev.groupby('hash')): # iterate over all hashes, providing a counter k, every hash h and its data hv
if False: # desperately not deleting this as broken_barh would save the innermost loop and would generally fit better I think...
pass
#ax.broken_barh(ev[['start', 'dur']].T, np.array([i*np.ones(len(ev))+k/10, .1*np.ones(len(ev))]).T)
else:
for n, (a, b) in enumerate(zip(hv.start, hv.end)): # iterate over every single event per hash, providing a counter n and start and stop time a and b
p = ax.plot([a, b], k*np.ones(2)+i/10, color=last_color, lw=15, label='_' if k>0 or n>0 else '' + e)
last_color = p[0].get_c() # setting color value to the last one used to prevent color cycling
ax.set_yticks(range(len(df.groupby('hash').groups)))
ax.set_yticklabels(map(brk_str, df.groupby('hash').groups))
ax.legend(ncol=2, bbox_to_anchor=[0, 0, 1, 1.1], loc=9, edgecolor='w')
plt.tight_layout()
结果plt.plot
:
推荐阅读
- r - 从 for 循环打印或返回字符串
- flutter - 颤动:我想显示一个包含文本列表()的换行,包括小时候的换行符,左对齐
- android-studio - 如何通过android studio扫描微条形码(micropdf417)
- r - 查找 group_by 条件为真的行比例的最佳方法
- ios - “增加对自动HTTPS升级的支持”的详细规格是什么?
- vue.js - 在Vue.js中按键获取单个项目
- angular - 为什么我的加载程序会破坏 fxLayout 行换行
- javascript - 为什么 node.bcrypt.js 的哈希密码直接以 salt 为前缀?
- spring-boot - IBM Mq 之间的消息消费和发布速度减慢
- bash - 带有 AND 的 Shell 脚本测试命令