☰Read-only archive⌕
Looking for help with Bokeh?

This is a read-only archive. Ask questions and join the conversation on GitHub.

Visit Community Support on GitHub →
Archived discussions · Captured October 28, 2026

CustomJS with Networkx Graph Edge Color Update

Community Support
Shammya_Saha
Shammya_Saha

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)
⌁   Link to post
gmerritt123
gmerritt123

In the CustomJS, you’re assigning a new line_color field to the source, which isn’t what you want. You want to the the glyph to derive its line_colors from a field based on the value of the select.

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;
        renderer.glyph.line_color = {'field':'edge_color_by_club'}
    } else if (value === 'random') {
        //renderer.data_source.data.line_color = data.edge_color_by_random;
        renderer.glyph.line_color = {'field':'edge_color_by_random'}
    }
    console.log(renderer.data_source.data);
    
    renderer.data_source.change.emit(); // Trigger the update
""")

An aside/alternative → I find CustomJSTransform super handy for theming stuff like this - it prevents you from having “color” fields in your CDS.

⌁   Link to post

End of archived discussion · Replies are disabled