Skip to content
Advertisement

Highlighting the neighborhood of a node on selection

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.

enter image description here

#!/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()
User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement