Streamlit中Plotly Express条形图排序异常,需手动重运行修复?
问题:Streamlit+Plotly条形图默认不按指定规则排序,仅重运行后生效
问题背景
使用Polars和Streamlit搭建的仪表板中,多个水平条形图需要按total_gmv的最大值升序排列,但默认打开页面、刷新、清除缓存后,图表均未正确排序。只有点击Streamlit右上角菜单的「重运行」后,图表才会显示正确的排序状态。本地Jupyter Notebook不通过Streamlit运行相同Plotly代码时,categoryorder='max ascending'同样不生效。
复现细节
- 无痕模式打开、刷新页面、清除Streamlit缓存后,问题依然存在
- 所有条形图都出现相同的排序异常
- 注释掉
update_yaxes中的categoryorder='max ascending'参数后,图表变为升序排序,但并非按total_gmv最大值的规则排序
相关代码片段
fig_pincode_gmv_facet = px.bar(df_pincode_gmv_facet(), x='total_gmv', y='pincode', facet_col='Year', orientation='h', labels={ "total_gmv": "Total GMV" }, category_orders={'Year': [2015, 2016]}, title=f'<b>Top 15 Pincodes by Total GMV in respective Years</b>' ).update_yaxes(type='category', categoryorder='max ascending') st.plotly_chart(fig_pincode_gmv_facet, use_container_width=True, config=config)
排查更新
- 移除
categoryorder='max ascending'后,图表自动按升序排列,但不符合需求 - 本地Jupyter单独运行Plotly代码时,
categoryorder='max ascending'参数未生效
可行解决方案建议
1. 提前在数据层面完成排序(推荐)
绕过Plotly的自动排序逻辑,直接在生成数据集时按需求排序,并将类别设置为物理顺序:
def df_pincode_gmv_facet(): # 原有数据处理逻辑... # 按Year分组,每组内按total_gmv升序排序,固定pincode的顺序 df = ( df.group_by('Year') .sort_by('total_gmv') .with_columns( pincode=pl.col('pincode').cast(pl.Categorical).cat.set_ordering('physical') ) ) return df
修改后,Plotly会直接沿用数据中pincode的物理顺序,无需依赖categoryorder参数。
2. 显式指定每个facet的y轴类别顺序
手动计算每个Year对应的pincode排序列表,通过categoryarray指定:
# 先获取数据集 df = df_pincode_gmv_facet() fig_pincode_gmv_facet = px.bar(df, x='total_gmv', y='pincode', facet_col='Year', orientation='h', labels={ "total_gmv": "Total GMV" }, category_orders={'Year': [2015, 2016]}, title=f'<b>Top 15 Pincodes by Total GMV in respective Years</b>' ).update_yaxes(type='category') # 为每个facet设置自定义排序 for idx, year in enumerate([2015, 2016], start=1): sorted_pincodes = df.filter(pl.col('Year') == year).sort('total_gmv')['pincode'].to_list() fig_pincode_gmv_facet.update_yaxes( categoryorder='array', categoryarray=sorted_pincodes, col=idx ) st.plotly_chart(fig_pincode_gmv_facet, use_container_width=True, config=config)
这种方式直接控制每个facet的y轴类别顺序,避免Plotly自动推断的不确定性。
3. 检查Streamlit缓存的影响
如果df_pincode_gmv_facet()使用了@st.cache_data装饰器,确保缓存的是已经排序完成的数据,或者在缓存函数内部执行排序逻辑,避免缓存的数据集顺序不符合预期。
内容的提问来源于stack exchange,提问作者ViSa
相关产品推荐
相关产品推荐

