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

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)

排查更新

  1. 移除categoryorder='max ascending'后,图表自动按升序排列,但不符合需求
  2. 本地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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 04:52:45