在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}**")
关键逻辑说明
- 会话状态存范围:用
st.session_state.current_x_range保存当前X轴的显示边界,页面重跑时不会丢失状态 - 捕获缩放事件:通过
plotly_chart.relayout_data获取用户缩放/平移后的X轴范围,只要检测到有效范围就更新会话状态 - 自动重算更新:调用
st.rerun()触发页面重新执行,重新筛选数据计算平均值并同步更新图表里的水平线 - 空数据防护:加入空数据判断,避免没有数据时计算均值报错
内容的提问来源于stack exchange,提问作者Thomas
相关产品推荐
相关产品推荐

