已排序DataFrame用Plotly绘图时X轴未按顺序显示问题
问题描述
我正在对多个DataFrame开展可视化绘图,绘图前已经完成所有相关DataFrame的排序,但最终生成的图表X轴没有按预期顺序排列,异常效果如下:
相关实现代码
fig = make_subplots(rows=2, cols=1, shared_xaxes=True, vertical_spacing=0.02) fig.add_trace(go.Scatter(x=df_login_s[df_login_s['tenant']==tenant]['mininterval'].dt.time, y=df_login_s[df_login_s['tenant']==tenant]['success_ct'], mode='lines', name='current_outage_success'), row=1, col=1) fig.add_trace(go.Scatter(x=df_login_s_p[df_login_s_p['tenant']==tenant]['mininterval'] , y=df_login_s_p[df_login_s_p['tenant']==tenant]['success_avg'], mode='markers', name='prior_weeks_success'), row=1, col=1) fig.add_trace(go.Scatter(x=df_login_f[df_login_f['tenant']==tenant]['mininterval'].dt.time, y=df_login_f[df_login_f['tenant']==tenant]['failure_ct'], mode='markers', name='current_outage_fail'), row=2, col=1) fig.add_trace(go.Scatter(x=df_login_f_p[df_login_f_p['tenant']==tenant]['mininterval'] , y=df_login_f_p[df_login_f_p['tenant']==tenant]['fail_avg'], mode='markers', name='prior_weeks_fail'), row=2, col=1) fig.update_xaxes( title_text = "Time (UTC)", row=2,col=1) fig.update_yaxes( title_text = "Success Login", title_standoff = 25,row=1, col=1) fig.update_yaxes( title_text = "Success Login", title_standoff = 25,row=1, col=1) fig.update_yaxes( title_text = "Fail Login", title_standoff = 25,row=2, col=1) fig.update_yaxes( title_text = "Fail Login", title_standoff = 25,row=2, col=1) fig.update_layout(height=800, width=1000, title="{},{}".format(tenant,single_date)) fig.show()
补充说明:绘图前已完成所有对应DataFrame的排序操作。
原因分析
X轴乱序和DataFrame本身是否排序无关,核心问题是传入Plotly的x值类型不统一:
df_login_s、df_login_f两个数据集的x值做了.dt.time转换,传入的是Python原生datetime.time对象df_login_s_p、df_login_f_p两个数据集的x值直接传入了pandas的datetime64类型列
Plotly遇到混合类型的x轴时,无法按时间顺序做统一轴排序,会默认按值的字符串字典序排列,最终出现顺序错乱。
修复方案
统一所有trace的x值类型即可解决问题,推荐两种实现方式:
- 方案一(推荐):所有trace统一直接传入
datetime64类型的mininterval列,不做.dt.time转换,最后通过x轴配置控制只显示时间部分,不会影响展示效果:fig.update_xaxes( tickformat="%H:%M", # 按小时:分钟格式显示时间 title_text = "Time (UTC)", row=2,col=1 ) - 方案二:如果确实需要使用
time类型,给四个trace的x值全部加上.dt.time转换,保证类型完全一致。
额外提示:当前代码中存在两组重复的update_yaxes调用,重复设置同一个子图的y轴属性没有实际作用,可以删除冗余代码精简逻辑。
内容的提问来源于stack exchange,提问作者Ramish
相关产品推荐
相关产品推荐

