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

如何用Plotly实现带固定节点的同步网络图与累积时序折线图

解决Plotly同步可视化的两个核心问题

问题1:网络图节点位置固定,仅更新颜色

问题根源

原代码为每个时间点创建独立的网络图Scatter trace,切换trace时易导致坐标轴范围变动,且存在冗余。正确思路是只保留一个网络图trace,通过滑块动态更新节点颜色属性,位置始终固定。

修改方案

  • 仅添加一次网络图trace,设置固定x、y坐标
  • 滑块的update方法中,仅修改该trace的marker.color属性,而非切换trace可见性

问题2:折线图累积展示历史数据

问题根源

原代码为每个节点的每个时间点创建单独trace,导致滑块拖动时多个trace叠加显示,不符合累积展示需求。正确思路是每个节点仅创建一个trace,通过滑块动态扩展该trace的x、y数据至当前时间点的历史范围。

修改方案

  • 每个节点仅添加一个初始trace(显示第一个时间点数据)
  • 滑块的update方法中,更新对应节点trace的x和y为times[:t+1]和activation_data[node][:t+1]

完整修正代码

import plotly.graph_objects as go
from plotly.subplots import make_subplots
import numpy as np

# 示例激活数据
times = np.arange(0, 10, 0.5)
nodes = ['A', 'B', 'C']
activation_data = {
    'A': np.sin(times),
    'B': np.cos(times),
    'C': np.sin(times + np.pi / 4)
}

# 节点固定颜色
node_colors = {
    'A': 'red',
    'B': 'blue',
    'C': 'green'
}

# 固定节点位置(可替换为实际业务坐标)
fixed_node_x = [1, 2, 3]
fixed_node_y = [1, 2, 3]

# 创建子图布局:上方折线图,下方网络图
fig = make_subplots(rows=2, cols=1, row_heights=[0.5, 0.5], vertical_spacing=0.15)

# 添加折线图:每个节点一个trace,初始仅显示第一个时间点数据
line_trace_indices = {}
for idx, node in enumerate(nodes):
    fig.add_trace(
        go.Scatter(
            x=[times[0]],
            y=[activation_data[node][0]],
            mode='lines+markers',
            line=dict(color=node_colors[node]),
            name=f'Node {node}'
        ),
        row=1, col=1
    )
    line_trace_indices[node] = idx

# 添加网络图:仅一个trace,固定位置,初始颜色为第一个时间点的激活值
network_trace_idx = len(nodes)
fig.add_trace(
    go.Scatter(
        x=fixed_node_x,
        y=fixed_node_y,
        mode='markers',
        marker=dict(
            size=20,
            color=[activation_data[node][0] for node in nodes],
            colorscale='Viridis',
            showscale=False
        ),
        name='Network Nodes'
    ),
    row=2, col=1
)

# 定义滑块步骤
steps = []
for t in range(len(times)):
    step = dict(
        method="update",
        args=[
            # 更新折线图数据和网络图颜色
            {
                'x': [times[:t+1] for _ in nodes] + [fixed_node_x],
                'y': [activation_data[node][:t+1] for node in nodes] + [fixed_node_y],
                'marker.color': [None]*len(nodes) + [[activation_data[node][t] for node in nodes]]
            },
            # 固定坐标轴范围,避免切换时偏移
            {
                'xaxis.range': [times[0], times[-1]],
                'xaxis2.range': [min(fixed_node_x)-0.5, max(fixed_node_x)+0.5],
                'yaxis2.range': [min(fixed_node_y)-0.5, max(fixed_node_y)+0.5]
            }
        ],
        label=f"t = {times[t]:.1f}",
    )
    steps.append(step)

# 添加滑块控件
sliders = [dict(
    active=0,
    currentvalue={"prefix": "当前时间: "},
    pad={"t": 50},
    steps=steps
)]

# 更新整体布局
fig.update_layout(
    sliders=sliders,
    height=600,
    title="同步网络图与折线图(时间滑块控制)",
    showlegend=True
)

# 强制固定网络图坐标轴范围,彻底避免位置偏移
fig.update_xaxes(row=2, col=1, range=[min(fixed_node_x)-0.5, max(fixed_node_x)+0.5])
fig.update_yaxes(row=2, col=1, range=[min(fixed_node_y)-0.5, max(fixed_node_y)+0.5])

fig.show()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 23:12:08