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

在Streamlit的Plotly图表中实现选中X区间数据平均值交互叠加

实现Streamlit+Plotly缩放时动态计算选中范围平均值

直接给你贴可运行的代码,靠Streamlit会话状态和Plotly的relayout事件就能搞定,不用复杂回调:

import streamlit as st
import plotly.express as px
import pandas as pd
import numpy as np

# 生成示例散点数据
np.random.seed(42)
x_values = np.random.uniform(0, 100, 200)
df_group1 = pd.DataFrame({'X': x_values, 'Y': np.random.normal(50, 10, 200)})
df_group2 = pd.DataFrame({'X': x_values, 'Y': np.random.normal(70, 15, 200)})

# 初始化会话状态,存储当前X轴显示范围
if 'current_x_range' not in st.session_state:
    st.session_state.current_x_range = [x_values.min(), x_values.max()]

# 根据当前X范围计算两组数据的Y平均值
filtered_group1 = df_group1[df_group1['X'].between(*st.session_state.current_x_range)]
avg_group1 = filtered_group1['Y'].mean() if not filtered_group1.empty else 0

filtered_group2 = df_group2[df_group2['X'].between(*st.session_state.current_x_range)]
avg_group2 = filtered_group2['Y'].mean() if not filtered_group2.empty else 0

# 创建Plotly图表
fig = px.scatter()
# 添加两组散点
fig.add_scatter(x=df_group1['X'], y=df_group1['Y'], name='Group 1', mode='markers', marker_color='#1f77b4')
fig.add_scatter(x=df_group2['X'], y=df_group2['Y'], name='Group 2', mode='markers', marker_color='#ff7f0e')
# 添加平均值水平线
fig.add_hline(y=avg_group1, line_dash='dash', line_color='#1f77b4', 
              annotation_text=f'Group 1 Avg: {avg_group1:.2f}', annotation_position='bottom right')
fig.add_hline(y=avg_group2, line_dash='dash', line_color='#ff7f0e', 
              annotation_text=f'Group 2 Avg: {avg_group2:.2f}', annotation_position='top right')
# 优化交互体验
fig.update_layout(hovermode='closest')

# 渲染图表并捕获缩放/平移事件
plotly_chart = st.plotly_chart(fig, config={'scrollZoom': True}, use_container_width=True)

# 检测缩放事件,更新X范围并触发页面重算
if plotly_chart.relayout_data:
    if 'xaxis.range[0]' in plotly_chart.relayout_data and 'xaxis.range[1]' in plotly_chart.relayout_data:
        st.session_state.current_x_range = [
            plotly_chart.relayout_data['xaxis.range[0]'],
            plotly_chart.relayout_data['xaxis.range[1]']
        ]
        st.rerun()

# 展示平均值结果
st.subheader("当前选中X范围的平均值")
st.write(f"- Group 1: **{avg_group1:.2f}**")
st.write(f"- Group 2: **{avg_group2:.2f}**")

关键逻辑说明

  1. 会话状态存范围:用st.session_state.current_x_range保存当前X轴的显示边界,页面重跑时不会丢失状态
  2. 捕获缩放事件:通过plotly_chart.relayout_data获取用户缩放/平移后的X轴范围,只要检测到有效范围就更新会话状态
  3. 自动重算更新:调用st.rerun()触发页面重新执行,重新筛选数据计算平均值并同步更新图表里的水平线
  4. 空数据防护:加入空数据判断,避免没有数据时计算均值报错

内容的提问来源于stack exchange,提问作者Thomas

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 07:32:06