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

使用Matplotlib与Pandas绘制堆叠时间型水平条形图报错求助

报错原因

你遇到的TypeError: invalid type promotion报错核心有两点:

  1. pandas内置的barh堆叠绘图逻辑默认仅支持数值型数据的堆叠,你传入的datetime时间对象属于时间类型,无法直接参与堆叠计算,触发类型错误
  2. 你代码里存储的是时间点而非每个堆叠段的时长,堆叠水平条形图的每一段需要的是宽度(时长),而非结束时间点,逻辑上也不匹配。

实现方案

绘制设备状态时间线更灵活的方案是直接用matplotlib原生的barh方法,通过left参数控制每个状态段的起始位置,自己管理堆叠逻辑,比pandas封装的绘图接口更适配时间线场景,完整可运行代码如下:

import datetime
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.dates as mdates

# 构造样本数据:每个设备对应多个状态段,含开始时间、持续时长(秒)、状态
device_status = [
    # 设备1的状态段
    {"device": "设备1", "start_time": datetime.datetime.now(), "duration": 10, "status": "可用"},
    {"device": "设备1", "start_time": datetime.datetime.now() + datetime.timedelta(seconds=10), "duration": 5, "status": "不可用"},
    {"device": "设备1", "start_time": datetime.datetime.now() + datetime.timedelta(seconds=15), "duration": 15, "status": "可用"},
    # 设备2的状态段
    {"device": "设备2", "start_time": datetime.datetime.now(), "duration": 3, "status": "不可用"},
    {"device": "设备2", "start_time": datetime.datetime.now() + datetime.timedelta(seconds=3), "duration": 17, "status": "可用"},
    {"device": "设备2", "start_time": datetime.datetime.now() + datetime.timedelta(seconds=20), "duration": 10, "status": "不可用"},
]
df = pd.DataFrame(device_status)

# 把datetime转成matplotlib可识别的数值时间格式
df["start_num"] = mdates.date2num(df["start_time"])
# 持续时长转成数值时间单位(matplotlib数值时间以天为单位,所以秒数除以86400)
df["duration_num"] = df["duration"] / 86400

# 初始化画布
fig, ax = plt.subplots(figsize=(10, 3))
# 设备名映射到y轴坐标
device_y_map = {device: idx for idx, device in enumerate(df["device"].unique())}
# 状态和颜色映射:可用绿色,不可用红色
color_map = {"可用": "green", "不可用": "red"}

# 逐个绘制每个状态段
for _, row in df.iterrows():
    ax.barh(
        y=device_y_map[row["device"]],
        width=row["duration_num"],
        left=row["start_num"],
        color=color_map[row["status"]],
        height=0.5
    )

# 配置坐标轴显示
ax.set_yticks(list(device_y_map.values()))
ax.set_yticklabels(list(device_y_map.keys()))
# x轴格式化为可读的时间格式
ax.xaxis.set_major_formatter(mdates.DateFormatter("%H:%M:%S"))
plt.xticks(rotation=45)
plt.xlabel("时间")
plt.ylabel("设备")
plt.tight_layout()
plt.show()

内容的提问来源于stack exchange,提问作者Manuel

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 20:36:01