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
相关产品推荐
相关产品推荐

