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

如何在Plotly/Plotly-Dash图表中动态展示可见数据的统计指标?

动态显示Plotly图表可见区域数据统计值

方案1:纯Plotly(导出HTML后仍可交互)

如果需要生成可独立运行的HTML文件,可通过嵌入JavaScript回调监听图表的视图变化,实时计算当前可见数据的统计值并更新标题。

完整代码

import plotly.graph_objects as go
import numpy as np
from plotly.io import write_html

# 生成示例数据
x = np.linspace(0, 2 * np.pi, 1000)
y = np.sin(x)

# 初始统计值
avg = np.mean(y)
min_val = np.min(y)
max_val = np.max(y)
std_dev = np.std(y)

# 创建图表
fig = go.Figure(
    data=go.Scatter(x=x, y=y, mode='lines'),
    layout=go.Layout(
        title=f'Sine Waveform\nAverage: {avg:.2f}, StdDev: {std_dev:.2f}, Min: {min_val:.2f}, Max: {max_val:.2f}',
        xaxis=dict(title='x'),
        yaxis=dict(title='y'),
        height=500
    )
)

# 添加JavaScript回调,监听视图变化
js_callback = """
<script>
var plot = document.getElementById('plot').data[0];
var x = plot.x;
var y = plot.y;

document.getElementById('plot').on('plotly_relayout', function(eventData) {
    // 获取当前x轴的可见范围
    var xRange = eventData['xaxis.range'] || [x[0], x[x.length-1]];
    // 筛选出可见范围内的y值
    var visibleY = y.filter((val, idx) => x[idx] >= xRange[0] && x[idx] <= xRange[1]);
    
    // 计算统计值
    var avg = visibleY.reduce((a, b) => a + b, 0) / visibleY.length;
    var stdDev = Math.sqrt(visibleY.reduce((a, b) => a + Math.pow(b - avg, 2), 0) / visibleY.length);
    var minVal = Math.min(...visibleY);
    var maxVal = Math.max(...visibleY);
    
    // 更新图表标题
    Plotly.relayout('plot', {
        title: `Sine Waveform\nAverage: ${avg.toFixed(2)}, StdDev: ${stdDev.toFixed(2)}, Min: ${minVal.toFixed(2)}, Max: ${maxVal.toFixed(2)}`
    });
});
</script>
"""

# 导出带回调的HTML文件
write_html(fig, 'dynamic_stats_plot.html', include_plotlyjs='cdn', post_script=js_callback, full_html=True)

说明

  • 运行代码后生成dynamic_stats_plot.html,打开后缩放/平移x轴,标题会自动更新为当前可见区域数据的统计值
  • 核心是通过plotly_relayout事件监听视图变化,筛选可见数据后计算统计值,再调用Plotly.relayout更新标题

方案2:Plotly Dash(交互式Web应用)

如果需要构建更复杂的交互式应用,用Dash框架可以更便捷地实现回调逻辑,还能添加额外的统计展示组件。

完整代码

import dash
from dash import dcc, html, Input, Output, State
import plotly.graph_objects as go
import numpy as np

# 生成示例数据
x = np.linspace(0, 2 * np.pi, 1000)
y = np.sin(x)

# 初始化Dash应用
app = dash.Dash(__name__)

# 应用布局
app.layout = html.Div([
    dcc.Graph(id='sine-plot', figure=go.Figure(
        data=go.Scatter(x=x, y=y, mode='lines'),
        layout=go.Layout(
            title='Sine Waveform',
            xaxis=dict(title='x'),
            yaxis=dict(title='y'),
            height=500
        )
    )),
    html.Div(id='stats-display', style={'margin-top': 20, 'font-size': 16})
])

# 回调函数:根据可见区域更新统计值
@app.callback(
    [Output('sine-plot', 'figure'), Output('stats-display', 'children')],
    [Input('sine-plot', 'relayoutData')],
    [State('sine-plot', 'figure')]
)
def update_stats(relayout_data, fig):
    # 获取当前x轴范围,默认显示全部数据
    if relayout_data and 'xaxis.range[0]' in relayout_data:
        x_min = relayout_data['xaxis.range[0]']
        x_max = relayout_data['xaxis.range[1]']
    else:
        x_min = x[0]
        x_max = x[-1]
    
    # 筛选可见数据
    mask = (x >= x_min) & (x <= x_max)
    visible_y = y[mask]
    
    # 计算统计值
    avg = np.mean(visible_y)
    std_dev = np.std(visible_y)
    min_val = np.min(visible_y)
    max_val = np.max(visible_y)
    
    # 更新图表标题
    fig['layout']['title'] = f'Sine Waveform\nAverage: {avg:.2f}, StdDev: {std_dev:.2f}, Min: {min_val:.2f}, Max: {max_val:.2f}'
    
    # 更新统计展示文本
    stats_text = [
        html.P(f'**Average**: {avg:.2f}'),
        html.P(f'**StdDev**: {std_dev:.2f}'),
        html.P(f'**Min Value**: {min_val:.2f}'),
        html.P(f'**Max Value**: {max_val:.2f}')
    ]
    
    return fig, stats_text

if __name__ == '__main__':
    app.run_server(debug=True)

说明

  • 运行后打开本地服务器地址(默认http://127.0.0.1:8050/),操作图表缩放/平移后,标题和下方的统计区域会同步更新
  • 相比纯HTML方案,Dash更适合扩展,比如添加下拉框选择统计类型、切换数据源等功能

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 08:12:36