I created a graph using networkx and I am trying to plot it using bokeh. Currently, I am able to highlight the node that I clicked on, as well as the edges linked to the selected node.
To reproduce the example, see the following code inspired from the official bokeh tutorial:
from bokeh.models.graphs import NodesAndLinkedEdges from bokeh.models import Circle, MultiLine,TapTool from bokeh.io import show, output_notebook from bokeh.plotting import figure import networkx as nx from bokeh.models import Range1d, Plot from bokeh.plotting import from_networkx G = nx.gnm_random_graph(15, 30) plot = Plot(x_range=Range1d(-2, 2), y_range=Range1d(-2 ,2)) graph = from_networkx(G, nx.spring_layout, scale=1.8, center=(0,0)) plot.renderers.append(graph) graph.node_renderer.glyph = Circle(size=25, fill_color='#2b83ba') graph.edge_renderer.glyph = MultiLine(line_color="#cccccc", line_alpha=0.8, line_width=2) graph.node_renderer.selection_glyph = Circle(size=25, fill_color='#abdda4') graph.edge_renderer.selection_glyph = MultiLine(line_color='#abdda4', line_width=4) graph.selection_policy = NodesAndLinkedEdges() plot.add_tools(TapTool()) show(plot)
I would like to be able to highlight not only the linked edges, but also the neighbors of the selected node. Does anybody knows how to do so? Thanks! I’ve looked through all the policies available for selection, but none of them allows me to do so.
Advertisement
Answer
I am open to any other package as well.
In netgraph, the InteractiveGraph
class implements your desired behaviour by default.
#!/usr/bin/env python import matplotlib.pyplot as plt import networkx as nx from netgraph import InteractiveGraph # pip install netgraph G = nx.gnm_random_graph(15, 30, seed=1) plot = InteractiveGraph(G, node_color='#2b83ba', edge_color="#cccccc", edge_alpha=0.8) plt.show()
You can also implement arbitrary “policies” using the EmphasizeOnHoverGraph
parent class. Here an MWE that demonstrates a range of possible behaviours:
import matplotlib.pyplot as plt from netgraph._main import EmphasizeOnHoverGraph edges = [(0, 1), (1, 2), (2, 0)] mapping = { 0 : [], # nothing is highlighted / everything is de-emphasized 1 : [1], # only the node being hovered over is highlighted 2 : [2, (1, 2), (2, 0), 1, 2], # the node, its neighbours and connecting edges are highlighted (same as default behaviour) (0, 1) : [(2, 0)], # another edge is highlighted (1, 2) : [(1, 2), 1, 2], # the edge, and its source and target nodes are highlighted (same as default behaviour) # (2, 0) # nothing happens when hovering over edge (2, 0) } fig, ax = plt.subplots(figsize=(10, 10)) plot = EmphasizeOnHoverGraph(edges, mouseover_highlight_mapping=mapping, node_labels=True, edge_labels=True, ax=ax) plt.show()