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

如何在Plotly Dash中通过交互控件切换NetworkX节点颜色集?

实现Plotly Dash中切换节点颜色集的交互功能

我已完成Plotly Dash结合NetworkX的最小工作示例,现在需要实现通过交互控件(按钮或滑块)切换图中节点的颜色集——现有多组节点颜色列表(每组对应每个节点的颜色),用于展示神经元激活状态,避免手动修改代码的繁琐操作。


修改后的完整代码(按钮切换版本)

"""Generates a graph in dash with color set switching."""

import dash
from dash import dcc, html, Input, Output
import networkx as nx
import plotly.graph_objs as go

# 创建图G
G = nx.DiGraph()
G.add_nodes_from([0, 1, 2])
G.add_edges_from(
    [
        (0, 1),
        (0, 2),
    ],
    weight=6,
)

# 节点位置
pos = {
    0: [0, 0],
    1: [1, 2],
    2: [2, 0],
}
for node in G.nodes:
    G.nodes[node]["pos"] = list(pos[node])

# 统一管理所有颜色集,新增颜色集直接追加到列表即可
color_sets = [
    ["rgb(31, 119, 180)", "rgb(255, 127, 14)", "rgb(44, 160, 44)"],  # 颜色集1
    ["rgb(10, 20, 30)", "rgb(255, 255, 0)", "rgb(0, 255, 255)"]     # 颜色集2
]
num_sets = len(color_sets)

# 预生成边轨迹(固定不变,提升性能)
edge_trace = go.Scatter(
    x=[],
    y=[],
    line=dict(width=0.5, color="#888"),
    hoverinfo="none",
    mode="lines",
)

for edge in G.edges():
    x0, y0 = G.nodes[edge[0]]["pos"]
    x1, y1 = G.nodes[edge[1]]["pos"]
    edge_trace["x"] += tuple([x0, x1, None])
    edge_trace["y"] += tuple([y0, y1, None])

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

app.layout = html.Div(
    [
        # 交互控制区域
        html.Div(
            [
                html.Button("上一页", id="prev-btn", n_clicks=0, style={"margin-right": "10px"}),
                html.Button("下一页", id="next-btn", n_clicks=0),
                html.Div(id="current-set-indicator", children="当前颜色集:1", style={"margin-left": "10px", "display": "inline-block"})
            ],
            style={"margin": "15px"}
        ),
        # 图展示区域
        dcc.Graph(id="graph")
    ]
)

@app.callback(
    [Output("graph", "figure"), Output("current-set-indicator", "children")],
    [Input("prev-btn", "n_clicks"), Input("next-btn", "n_clicks")]
)
def update_color_set(prev_clicks, next_clicks):
    # 判断触发回调的按钮,计算当前颜色集索引(循环切换)
    ctx = dash.callback_context
    if not ctx.triggered:
        current_idx = 0
    else:
        button_id = ctx.triggered[0]["prop_id"].split(".")[0]
        if button_id == "next-btn":
            current_idx = (prev_clicks + next_clicks) % num_sets
        else:
            current_idx = (next_clicks - prev_clicks) % num_sets
    
    # 生成当前颜色集对应的节点轨迹
    node_trace = go.Scatter(
        x=[],
        y=[],
        text=[str(node) for node in G.nodes()],
        mode="markers",
        hoverinfo="text",
        marker=dict(size=30, color=color_sets[current_idx]),
    )
    for node in G.nodes():
        x, y = G.nodes[node]["pos"]
        node_trace["x"] += tuple([x])
        node_trace["y"] += tuple([y])
    
    # 组装完整图表
    fig = go.Figure(
        data=[edge_trace, node_trace],
        layout=go.Layout(
            xaxis=dict(showgrid=True, zeroline=True, showticklabels=True),
            yaxis=dict(showgrid=False, zeroline=False, showticklabels=False),
            height=400
        ),
    )
    
    return fig, f"当前颜色集:{current_idx + 1}"

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

滑块切换版本(可选)

如果偏好滑块控件,可替换布局和回调函数:

替换布局中的控制区域

# 滑块控制区域
html.Div(
    [
        dcc.Slider(
            id="color-set-slider",
            min=0,
            max=num_sets-1,
            step=1,
            value=0,
            marks={i: f"颜色集{i+1}" for i in range(num_sets)}
        )
    ],
    style={"margin": "15px", "width": "50%"}
),

替换回调函数

@app.callback(
    Output("graph", "figure"),
    Input("color-set-slider", "value")
)
def update_color_set_slider(current_idx):
    # 生成当前颜色集对应的节点轨迹
    node_trace = go.Scatter(
        x=[],
        y=[],
        text=[str(node) for node in G.nodes()],
        mode="markers",
        hoverinfo="text",
        marker=dict(size=30, color=color_sets[current_idx]),
    )
    for node in G.nodes():
        x, y = G.nodes[node]["pos"]
        node_trace["x"] += tuple([x])
        node_trace["y"] += tuple([y])
    
    # 组装完整图表
    fig = go.Figure(
        data=[edge_trace, node_trace],
        layout=go.Layout(
            xaxis=dict(showgrid=True, zeroline=True, showticklabels=True),
            yaxis=dict(showgrid=False, zeroline=False, showticklabels=False),
            height=400
        ),
    )
    
    return fig

关键修改说明

  1. 颜色集统一管理:将所有颜色集存入color_sets列表,新增颜色集只需追加元素,无需修改核心逻辑。
  2. 交互控件集成:添加按钮/滑块控件,让用户直观触发颜色切换操作。
  3. 动态更新逻辑:通过Dash回调函数监听控件事件,计算当前颜色集索引,实时更新节点的颜色属性。
  4. 性能优化:预生成固定不变的边轨迹,避免每次回调重复计算。

内容的提问来源于stack exchange,提问作者a.t.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 15:10:40