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

Plotly Express timeline在Streamlit中报错:timedelta无法JSON序列化

问题描述

在Streamlit中使用px.timeline绘制甘特图时,即便使用官方测试数据,也会抛出如下错误:

TypeError: Object of type timedelta is not JSON serializable

示例代码:

import plotly.express as px
import pandas as pd
import streamlit as st

df = pd.DataFrame([
    dict(Task="Job A", Start='2009-01-01', Finish='2009-02-28'),
    dict(Task="Job B", Start='2009-03-05', Finish='2009-04-15'),
    dict(Task="Job C", Start='2009-02-20', Finish='2009-05-30')
])

fig = px.timeline(df, x_start="Start", x_end="Finish", y="Task")
fig.update_yaxes(autorange="reversed") # 反转Y轴,让任务从上到下排列
st.plotly_chart(fig)

解决方法

该错误源于px.timeline生成的图表包含timedelta类型数据,而Streamlit在序列化Plotly图表至JSON时无法处理此类型。以下是两种可行的解决方式:

方法1:显式转换日期类型并指定X轴类型

将Start和Finish列转换为datetime格式,同时在创建图表时指定xaxis_type="date",强制Plotly使用日期类型而非时间差:

import plotly.express as px
import pandas as pd
import streamlit as st

df = pd.DataFrame([
    dict(Task="Job A", Start='2009-01-01', Finish='2009-02-28'),
    dict(Task="Job B", Start='2009-03-05', Finish='2009-04-15'),
    dict(Task="Job C", Start='2009-02-20', Finish='2009-05-30')
])

# 转换列为datetime类型
df['Start'] = pd.to_datetime(df['Start'])
df['Finish'] = pd.to_datetime(df['Finish'])

# 指定x轴为日期类型
fig = px.timeline(df, x_start="Start", x_end="Finish", y="Task", xaxis_type="date")
fig.update_yaxes(autorange="reversed")
st.plotly_chart(fig)

方法2:自定义JSON编码器处理timedelta

若需保留timedelta相关逻辑,可通过自定义JSON编码器将timedelta转换为毫秒数后再序列化:

import plotly.express as px
import pandas as pd
import streamlit as st
import json
from datetime import timedelta

# 自定义编码器,将timedelta转为毫秒
class TimedeltaEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, timedelta):
            return obj.total_seconds() * 1000
        return super().default(obj)

df = pd.DataFrame([
    dict(Task="Job A", Start='2009-01-01', Finish='2009-02-28'),
    dict(Task="Job B", Start='2009-03-05', Finish='2009-04-15'),
    dict(Task="Job C", Start='2009-02-20', Finish='2009-05-30')
])

fig = px.timeline(df, x_start="Start", x_end="Finish", y="Task")
fig.update_yaxes(autorange="reversed")

# 序列化后重新加载图表
fig_json = json.dumps(fig.to_dict(), cls=TimedeltaEncoder)
fig = px.from_json(fig_json)

st.plotly_chart(fig)

说明

优先推荐方法1,其操作简洁且符合Plotly与Streamlit的常规使用流程;方法2适用于需要特殊处理timedelta的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 23:05:21