You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于嵌套DataFrame的Matplotlib时间序列条形图绘制问题

实现PartId事件时间间隔的条形图绘制

核心思路

要实现每个PartId下相邻事件的时间间隔条形图,关键是把每个事件的起始时间和到下一个事件的时间差拆解出来,再用水平条形图(barh)把这些间隔对应到每个PartId的y轴位置上。

步骤拆解与代码实现

假设你的原始DataFrame结构是每条记录包含PartId和嵌套的Events列表(每个Event带EventTime字段),按以下步骤处理:

1. 数据预处理:提取并整理时间序列

先把嵌套的事件时间提取出来,转换成datetime类型并排序,再计算相邻时间的间隔:

import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.dates import DateFormatter

# 替换成你实际的DataFrame
df = pd.DataFrame({
    'PartId': ['A', 'B'],
    'Events': [
        [{'EventTime': '2023-01-01'}, {'EventTime': '2023-01-03'}, {'EventTime': '2023-01-06'}],
        [{'EventTime': '2023-01-02'}, {'EventTime': '2023-01-05'}]
    ]
})

# 提取每个PartId的事件时间,转成datetime并排序
df['EventTimes'] = df['Events'].apply(
    lambda x: sorted(pd.to_datetime([event['EventTime'] for event in x]))
)

# 生成每个间隔的起始、结束时间对
df['TimeIntervals'] = df['EventTimes'].apply(lambda times: list(zip(times[:-1], times[1:])))

# 展开成扁平化的间隔数据
interval_data = []
for _, row in df.iterrows():
    for start, end in row['TimeIntervals']:
        interval_data.append({
            'PartId': row['PartId'],
            'Start': start,
            'Duration': end - start
        })
interval_df = pd.DataFrame(interval_data)

2. 映射PartId到y轴数值位置

Matplotlib的条形图需要y轴是数值,所以给每个PartId分配一个固定的y坐标:

part_map = {part: idx for idx, part in enumerate(interval_df['PartId'].unique())}
interval_df['Y'] = interval_df['PartId'].map(part_map)

3. 绘制时间间隔条形图

用barh绘制水平条形图,设置起始时间为left参数,条形宽度为时间间隔(转换成天数方便显示):

plt.figure(figsize=(10, 6))

# 绘制条形:y轴是PartId对应的数值,宽度是间隔天数,起始位置是事件开始时间
plt.barh(
    interval_df['Y'],
    width=interval_df['Duration'].dt.days,  # 若要更精细可用.total_seconds()/3600转成小时
    left=interval_df['Start'],
    height=0.6,
    color='#4682B4'
)

# 配置y轴标签,替换回PartId
plt.yticks(ticks=list(part_map.values()), labels=list(part_map.keys()))

# 配置x轴时间格式,自动旋转标签避免重叠
plt.gca().xaxis.set_major_formatter(DateFormatter('%Y-%m-%d'))
plt.gcf().autofmt_xdate()

# 添加标题和轴标签
plt.title('各PartId事件时间间隔分布')
plt.xlabel('时间')
plt.ylabel('PartId')

plt.tight_layout()
plt.show()

常见问题排查

  • 时间类型错误:必须把EventTime转成datetime类型,否则无法计算时间差。
  • 事件未排序:如果事件时间乱序,间隔计算会完全错误,一定要先排序。
  • 条形方向错误:用barh而不是bar,这样PartId在y轴,时间在x轴,符合时间序列的展示逻辑。
  • 间隔单位问题:Matplotlib的width需要数值,所以要把时间差转换成天数、小时等数值单位。

内容的提问来源于stack exchange,提问作者Anne Høgdahl Skjærseth

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 03:05:18