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

Dash Plotly不通过pandas处理实现多条trace数值累加为单条trace的方案

实现方案

方案1:Dash服务端直接处理已生成的figure trace数据

该方案不需要对原始数据集做pandas预处理,直接读取你已经生成的fig_a中所有trace的坐标数据,按时间对齐累加后生成新的汇总图表即可,实现成本最低。
修改后的完整代码如下:

import pandas as pd
import numpy as np
import plotly.express as px
import plotly.graph_objects as go
from dash.dependencies import Output, Input
from dash import dcc
from dash import html
import dash

# 原始生成数据和分类型图表的逻辑不变
df_a = pd.DataFrame({"time":pd.Series(pd.date_range("1-nov-2021","2-nov-2021", freq="S")).sample(60),
             "bacteria_count":np.random.randint(0,500, 60), "bacteria_type":np.random.choice(list("ABCDEFGHIJKL"),60)})

df_a["epoch_time_ms"] = df_a["time"].astype(int) / 1000
df_a = df_a.sort_values("time")
fig_a = px.line(df_a, x="time", y="bacteria_count", line_shape="hv", color='bacteria_type')
fig_a.update_layout(hovermode='x unified')

# 新增:直接从fig_a的trace中提取数据累加,不需要碰原始df
all_x = set()
trace_data = []
for trace in fig_a.data:
    x_list = list(trace.x)
    y_list = list(trace.y)
    all_x.update(x_list)
    trace_data.append(dict(zip(x_list, y_list)))
# 按时间排序后累加y值
sorted_x = sorted(all_x)
sum_y = []
for x in sorted_x:
    current_sum = 0
    for td in trace_data:
        current_sum += td.get(x, 0)
    sum_y.append(current_sum)
# 生成汇总图表
fig_total = go.Figure(go.Scatter(x=sorted_x, y=sum_y, line_shape='hv', name='总细菌数'))
fig_total.update_layout(title='所有类型细菌总数', hovermode='x unified')

app = dash.Dash(__name__)
app.layout = html.Div(children=[
    html.Div([
        html.Div([
            html.H1(children='G_A'),
            dcc.Graph(id='fig_a-graph', figure=fig_a)
        ], className='row'),
        # 新增汇总图表容器
        html.Div([
            html.H1(children='总计数'),
            dcc.Graph(id='fig_total-graph', figure=fig_total)
        ], className='row')
    ])
])

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

方案2:客户端JS回调实现纯前端累加(和Grafana前端堆叠逻辑一致)

如果你需要完全在浏览器端完成计算(不需要服务端参与,和你提到的Grafana功能逻辑完全相同),可以使用Dash的客户端回调,通过JS读取已有图表的trace数据累加后渲染,不需要修改服务端数据处理逻辑。
核心实现逻辑是添加如下客户端回调:

dash.clientside_callback(
    """
    function(fig_a) {
        // 收集所有x值
        const allX = new Set();
        const traceMap = [];
        fig_a.data.forEach(trace => {
            const xList = trace.x;
            const yList = trace.y;
            const map = {};
            for(let i=0;i<xList.length;i++) {
                map[xList[i]] = yList[i];
                allX.add(xList[i]);
            }
            traceMap.push(map);
        });
        // 排序后累加
        const sortedX = Array.from(allX).sort();
        const sumY = sortedX.map(x => {
            return traceMap.reduce((sum, map) => sum + (map[x] || 0), 0);
        });
        // 返回新的figure
        return {
            data: [{x: sortedX, y: sumY, line_shape: 'hv', name: '总细菌数', type: 'scatter'}],
            layout: {title: '所有类型细菌总数', hovermode: 'x unified'}
        }
    }
    """,
    Output('fig_total-graph', 'figure'),
    Input('fig_a-graph', 'figure')
)

该方案的优势是完全在前端执行计算,即便后续你通过交互过滤了fig_a中的部分trace,汇总图表也会自动同步更新,和Grafana的堆叠功能表现一致。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 14:24:03