使用add_trace()向go.Figure添加px.timeline异常问题求助
解决Plotly中px.timeline添加到go.Figure后X轴时间显示异常问题
当尝试将px.timeline生成的图表添加到已有go.Figure(比如包含go.Scatter的图表)时,直接通过add_trace提取px.timeline().data[0]添加会导致X轴无法正常显示时间,而单独使用px.timeline时显示正常。以下是复现代码:
import pandas as pd import plotly.graph_objects as go import plotly.express as px mydata_as_json = '{"Start_Time":{"0":"2023-11-01 16:48:24.8","1":"2023-11-01 16:49:47.7","2":"2023-11-01 16:53:23.3","3":"2023-11-01 16:56:08.6","4":"2023-11-01 16:58:37.9","5":"2023-11-01 17:00:10.9"},"End_Time":{"0":"2023-11-01 16:48:37.7","1":"2023-11-01 16:51:44.3","2":"2023-11-01 16:54:00.2","3":"2023-11-01 16:57:23.4","4":"2023-11-01 16:58:56.8","5":"2023-11-01 17:01:59.1"},"Instr":{"0":"MVIC","1":"LEISA","2":"MVIC","3":"LEISA","4":"MVIC","5":"LEISA"}}' df = pd.DataFrame(eval(mydata_as_json)) # 正常显示的时间轴 fig_good = px.timeline( df, x_start="Start_Time", x_end="End_Time", y="Instr", ) fig_good.show() # 异常的时间轴:X轴不显示时间 fig_bad = go.Figure() fig_bad = fig_bad.add_trace( px.timeline( df, x_start='Start_Time', x_end='End_Time', y='Instr', ).data[0] ) fig_bad.show()
问题原因
px.timeline生成的Figure对象不仅包含数据(trace),还自动配置了X轴的类型为date,并设置了时间范围等布局参数。而直接提取data[0]添加到新的go.Figure时,这些关键的轴布局配置不会被自动继承,新Figure默认X轴为线性类型,导致时间数据被解析为数值,无法正常显示时间格式。
解决方案
方案1:复用px.timeline的布局配置
先创建px.timeline的完整Figure,然后将其trace和布局配置分别添加到目标go.Figure中:
import pandas as pd import plotly.graph_objects as go import plotly.express as px mydata_as_json = '{"Start_Time":{"0":"2023-11-01 16:48:24.8","1":"2023-11-01 16:49:47.7","2":"2023-11-01 16:53:23.3","3":"2023-11-01 16:56:08.6","4":"2023-11-01 16:58:37.9","5":"2023-11-01 17:00:10.9"},"End_Time":{"0":"2023-11-01 16:48:37.7","1":"2023-11-01 16:51:44.3","2":"2023-11-01 16:54:00.2","3":"2023-11-01 16:57:23.4","4":"2023-11-01 16:58:56.8","5":"2023-11-01 17:01:59.1"},"Instr":{"0":"MVIC","1":"LEISA","2":"MVIC","3":"LEISA","4":"MVIC","5":"LEISA"}}' df = pd.DataFrame(eval(mydata_as_json)) # 创建目标Figure(可提前添加其他trace,比如go.Scatter) fig_target = go.Figure() # 生成px.timeline的完整Figure对象 px_timeline_fig = px.timeline(df, x_start='Start_Time', x_end='End_Time', y='Instr') # 添加时间轴trace到目标Figure fig_target.add_trace(px_timeline_fig.data[0]) # 复用px.timeline的X轴布局配置 fig_target.update_layout(xaxis=px_timeline_fig.layout.xaxis) # 如果需要保留原Figure的其他布局,也可以仅设置X轴类型 # fig_target.update_layout(xaxis_type='date') fig_target.show()
方案2:手动构造go.Bar实现时间轴
px.timeline本质是基于go.Bar(横向)实现的,因此可以直接用go.Bar手动构造时间轴trace,并显式设置X轴类型:
import pandas as pd import plotly.graph_objects as go import plotly.express as px mydata_as_json = '{"Start_Time":{"0":"2023-11-01 16:48:24.8","1":"2023-11-01 16:49:47.7","2":"2023-11-01 16:53:23.3","3":"2023-11-01 16:56:08.6","4":"2023-11-01 16:58:37.9","5":"2023-11-01 17:00:10.9"},"End_Time":{"0":"2023-11-01 16:48:37.7","1":"2023-11-01 16:51:44.3","2":"2023-11-01 16:54:00.2","3":"2023-11-01 16:57:23.4","4":"2023-11-01 16:58:56.8","5":"2023-11-01 17:01:59.1"},"Instr":{"0":"MVIC","1":"LEISA","2":"MVIC","3":"LEISA","4":"MVIC","5":"LEISA"}}' df = pd.DataFrame(eval(mydata_as_json)) # 转换时间列为datetime类型 df['Start_Time'] = pd.to_datetime(df['Start_Time']) df['End_Time'] = pd.to_datetime(df['End_Time']) # 计算持续时间 df['Duration'] = df['End_Time'] - df['Start_Time'] # 创建目标Figure fig_target = go.Figure() # 添加手动构造的时间轴trace fig_target.add_trace(go.Bar( y=df['Instr'], x=df['Duration'], x0=df['Start_Time'], orientation='h', name='Timeline' )) # 显式设置X轴为时间类型 fig_target.update_layout(xaxis_type='date') fig_target.show()
内容的提问来源于stack exchange,提问作者Emma Birath
相关产品推荐
相关产品推荐

