Hello
I have been trying to create a Network Graph while using a select to change the color of the edges with CustomJS. I am not sure whether it is either possible or not at all.
The idea for me was - upon user’s selection on the Dropdown - I was going to the change the edge rendered. I think because Multiline is a python class - it is not possible. In that scenario - what can I do?
Here is the code
import networkx as nx
from bokeh.io import show
from bokeh.layouts import column
from bokeh.models import (BoxZoomTool, Circle, HoverTool,
MultiLine, Plot, Range1d, ResetTool)
from bokeh.models import CustomJS, Select
from bokeh.palettes import Spectral4
from bokeh.plotting import from_networkx
G = nx.karate_club_graph()
SAME_CLUB_COLOR, DIFFERENT_CLUB_COLOR = "black", "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_by_club")
color_list = ['black', 'red', 'blue']
counter = 0
for start_node, end_node, _ in G.edges(data=True):
edge_color = color_list[int(counter % 3)]
edge_attrs[(start_node, end_node)] = edge_color
counter += 1
nx.set_edge_attributes(G, edge_attrs, "edge_color_by_random")
# Show with Bokeh
plot = Plot(width=1200, height=1200,
x_range=Range1d(-1.1, 1.1), y_range=Range1d(-1.1, 1.1))
plot.title.text = "Graph Interaction Demonstration"
node_hover_tool = HoverTool(tooltips=[("index", "@index"), ("club", "@club")])
plot.add_tools(node_hover_tool, BoxZoomTool(), ResetTool())
graph_renderer = from_networkx(G, nx.spring_layout, scale=1, center=(0, 0))
graph_renderer.node_renderer.glyph = Circle(size=15, fill_color=Spectral4[0])
graph_renderer.edge_renderer.glyph = MultiLine(line_color="edge_color_by_club", line_alpha=0.8, line_width=1)
plot.renderers.append(graph_renderer)
dropdown_list = ['club','random']
x_select = Select(
options=dropdown_list,
value=dropdown_list[0],)
callback = CustomJS(args=dict(renderer=plot.renderers[0].edge_renderer), code="""
const data = renderer.data_source.data;
const value = cb_obj.value; // Get the selected value from the dropdown
if (value === 'club') {
renderer.data_source.data.line_color = data.edge_color_by_club;
} else if (value === 'random') {
renderer.data_source.data.line_color = data.edge_color_by_random;
}
console.log(renderer.data_source.data);
renderer.data_source.change.emit(); // Trigger the update
""")
x_select.js_on_change("value", callback)
layout = column(x_select, plot)
show(layout)