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

Bokeh绘制网络图时Select组件js_on_change事件无响应如何解决

问题根因

你当前的实现存在3个核心问题导致切换选择无效果:

  • 你自行创建的source和网络图实际渲染使用的数据源没有关联:from_networkx生成的渲染对象中,network_graph.edge_renderer.data_source才是负责边渲染的有效数据源,修改你自定义的source不会触达渲染层
  • 切换选择的回调逻辑只修改了weight字段值,没有执行「过滤weight>0的边」的核心逻辑
  • 初始化建图时仅传入了过滤后的边数据,JS侧没有全量边数据可用于切换后重新计算

修复后可运行代码

import networkx as nx
import pandas as pd
from bokeh.plotting import from_networkx, figure, show
from bokeh.models import Range1d, MultiLine, HoverTool, CustomJS, Select, Column

# 生成测试数据
d = {'weight': [1, 2,3,1,2], 'var': ["var1","var1","var1","var2", "var2"], 'source': ["a", "b","c","e","f"], 'target': ["c","g","e","a","h"]}
df1 = pd.DataFrame(data=d)
df2 = df1.pivot(index= ["source","target"], values = "weight", columns = "var").reset_index()
df2 = df2.fillna(0)

# 基础绘图配置
HOVER_TOOLTIPS = [("Search Term", "@index")]
title = "my title"
plot = figure(tooltips = HOVER_TOOLTIPS,
              tools="pan,wheel_zoom", 
              active_scroll='wheel_zoom',
              x_range=Range1d(-10.1, 10.1), 
              y_range=Range1d(-10.1, 10.1), 
              title=title, plot_width=1000
             )

category_default = "var1"
unique_categories = ["var1","var2"]

# 初始化用过滤后的数据建图
init_df = df2[df2[category_default] > 0][["source", "target", category_default]].rename(columns={category_default: "weight"})
G = nx.from_pandas_edgelist(init_df, edge_attr = "weight")
network_graph = from_networkx(G, nx.spring_layout, scale=10, center=(0, 0))
network_graph.edge_renderer.glyph = MultiLine(line_alpha=0.5, line_width="weight")
plot.renderers.append(network_graph)

# 下拉控件配置
select = Select(title='Category Selection', value=category_default, options=unique_categories)

# 回调逻辑:传入全量数据和网络图的边数据源
callback = CustomJS(
    args={
        "all_edges": df2.to_dict("list"), 
        "edge_source": network_graph.edge_renderer.data_source
    },
    code="""
        const selected_var = cb_obj.value;
        const sources = all_edges.source;
        const targets = all_edges.target;
        const weights = all_edges[selected_var];
        
        // 过滤weight>0的边
        const new_sources = [];
        const new_targets = [];
        const new_weights = [];
        for (let i = 0; i < sources.length; i++) {
            if (weights[i] > 0) {
                new_sources.push(sources[i]);
                new_targets.push(targets[i]);
                new_weights.push(weights[i]);
            }
        }
        
        // 更新边数据源
        edge_source.data = {
            'start': new_sources,
            'end': new_targets,
            'weight': new_weights
        };
        edge_source.change.emit();
    """
)

select.js_on_change("value", callback)
show(Column(plot, select))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 06:45:02