I have a dataset where the NetworkX graph is sized and colored by the degree attribute. I am looking to add a slider to the graph so that depending on the degree that is selected, the graph will dynamically update the nodes and edges. I have the slider showing up in Jupyter, however, it's not updating when selecting a new value. Any advice on how this can be done? Here is my code that I am working with currently:
df = pd.read_csv('data/book1.csv')
G = nx.from_pandas_edgelist(df, 'Node', 'Target', 'SimScore')
#Reference: https://stackoverflow.com/questions/18218931/find-highest-weight-edges-for-a-given-node
#Calculate degree for each node and remove instances when less than user defined threshold
for node in G.nodes():
edges = G.edges(node, data = True)
if len(edges) > 0:
for edge in list(edges):
if edge[2]['SimScore'] < 5:
G.remove_edge(edge[0], edge[1])
#Reference: https://stackoverflow.com/questions/18261587/python-networkx-remove-nodes-and-edges-with-some-condition
remove = [node for node, degree in G.degree() if degree == 0]
G.remove_nodes_from(remove)
G_dict = dict(G.degree())
#Add degree as node attribute
nx.set_node_attributes(G, name = 'degree', values = G_dict)
#Define color pallete
color_palette = Reds8
#Show hover tooltip with "nodes" being the user input songs and the degree
#Reference: https://docs.bokeh.org/en/latest/docs/user_guide/tools.html#hovertool
TOOLTIPS = [("Song", "@index"), ("Degree", "@degree")]
#Create plot with tooltips, ranges, and title
plot = figure(tooltips = TOOLTIPS, tools = "pan, wheel_zoom, save, reset", active_scroll = "wheel_zoom", x_range = Range1d(-10.1, 10.1), y_range = Range1d(-10.1, 10.1), title = "New Music Network Graph")
#Network graph object
networkG = from_networkx(G, networkx.spring_layout, scale = 10, center = (0,0))
#Set node size and color
min_degree = min(networkG.node_renderer.data_source.data['degree'])
max_degree = max(networkG.node_renderer.data_source.data['degree'])
networkG.node_renderer.glyph = Circle(size = 'degree', fill_color = linear_cmap('degree', color_palette, min_degree, max_degree))
networkG.edge_renderer.glyph = MultiLine(line_alpha = 0.5, line_width = 1)
plot.renderers.append(networkG)
########### Slider ###########
G_dict_slider = {'Nodes': list(G_dict.keys()), 'Degrees': list(G_dict.values())}
source = ColumnDataSource(data = G_dict_slider)
degree_slider = Slider(start = min_degree, end = max_degree, value = 20, step = 1, title = "Degrees")
callback = CustomJS(args = dict(source = source, deg = degree_slider), code = '''
const new_data = source.data;
const new_nodes = new_data['Node'];
const new_degrees = new_data['Degrees'];
var new_min_degree = min(networkG.node_renderer.data_source.new_degrees);
var new_max_degree = max(networkG.node_renderer.data_source.new_degrees);
networkG.node_renderer.glyph = Circle(size = new_degrees, fill_color = linear_cmap(new_degrees, color_palette, new_min_degree, new_max_degree));
networkG.edge_renderer.glyph = MultiLine(line_alpha = 0.5, line_width = 1);
source.change.emit();
''')
degree_slider.js_on_change('value', callback)
layout = row(plot, column(degree_slider),)
show(layout)
Here is the current output: Networkx Graph
Thanks in advance!