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
相关产品推荐
相关产品推荐

