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

Python Bokeh:CustomJS无法更新NetworkRenderer节点颜色问题咨询

问题:Bokeh中NetworkRenderer节点颜色无法通过CustomJS正常更新

我想通过JS回调选择不同的底层数据,更改NetworkRenderer对象中节点的颜色,但除非使用特殊技巧,否则图表不会实际更新。

我尝试使用CustomJS修改node_renderer的fill_value属性,使其使用node_renderer.data_source中的不同列,但图表并未更新(尽管在浏览器控制台中可看到fill_value已正确修改)。

目前唯一能让颜色实际更新的方法是:将不同数据复制到node_renderer.data_source中,还需通过js_link方法运行另一个修改节点属性的回调(本例用微调器改节点大小)才会触发颜色更新,且每次更改都需重复此操作。

我认为这不是正常行为,请问这是Bug还是我的代码问题?

原测试代码

import numpy as np
import networkx as nx

from bokeh.models import Circle, MultiLine, Select, Spinner, CustomJS, ColumnDataSource
from bokeh.plotting import figure, from_networkx, show
from bokeh.palettes import Viridis256
from bokeh.layouts import column

# 基于官方示例修改
G = nx.karate_club_graph()

SAME_CLUB_COLOR, DIFFERENT_CLUB_COLOR = "darkgrey", "red"

edge_attrs = {}
for start_node, end_node, _ in G.edges(data=True):
    edge_color = SAME_CLUB_COLOR if G.nodes[start_node]["club"] == G.nodes[end_node]["club"] else DIFFERENT_CLUB_COLOR
    edge_attrs[(start_node, end_node)] = edge_color

nx.set_edge_attributes(G, edge_attrs, "edge_color")

plot = figure(width=400, height=400, x_range=(-1.2, 1.2), y_range=(-1.2, 1.2),
              x_axis_location=None, y_axis_location=None, toolbar_location=None,
              title="Graph Interaction Demo", background_fill_color="#efefef",
              tooltips="index: @index, club: @club")
plot.grid.grid_line_color = None

graph_renderer = from_networkx(G, nx.spring_layout, scale=1, center=(0, 0))

# 节点颜色的随机数据
cds = ColumnDataSource({'Colors1': [Viridis256[int(val*255)] for val in np.random.rand(len(G.nodes))], 
                        'Colors2': [Viridis256[int(val*255)] for val in np.random.rand(len(G.nodes))]})
# 复制到node_renderer的数据源中
graph_renderer.node_renderer.data_source.data['color'] = cds.data['Colors1']

graph_renderer.node_renderer.glyph = Circle(size=15, fill_color="color")
graph_renderer.edge_renderer.glyph = MultiLine(line_color="edge_color",
                                               line_alpha=1, line_width=2)

# 定义交互控件
sel = Select(value='Colors1', options=['Colors1', 'Colors2'])
spin = Spinner(title="Glyph size", low=1, high=40, step=0.5, value=10, width=80)

callback = CustomJS(args=dict(graph_renderer=graph_renderer, cds=cds), 
                    code="""
                    var selection = cb_obj.value
                    graph_renderer.node_renderer.data_source.data['color'] = cds.data[selection]
                    graph_renderer.node_renderer.change.emit()
                    """)

sel.js_on_change('value', callback)
spin.js_link('value', graph_renderer.node_renderer.glyph, 'size')

# 生成图表
plot.renderers.append(graph_renderer)
my_lay = column(sel, spin, plot)
show(my_lay)

修正后的回调代码

方便其他遇到相同问题的开发者参考,根据已采纳的答案,正确的回调代码如下:

callback = CustomJS(args=dict(graph_renderer_ds=graph_renderer.node_renderer.data_source, cds=cds), 
                    code="""
                    var selection = cb_obj.value

                    graph_renderer_ds.data['color'] = cds.data[selection]
                    graph_renderer_ds.change.emit()
                    """)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 02:35:36