nandz123
nandz123

Reputation: 169

How to display list of connections in a networkx graph?

I currently have the following code for my networkx weighted graph:

import matplotlib.pyplot as plt
import networkx as nx

G = nx.Graph()

G.add_edge("sam", "ben", weight=0.6)
G.add_edge("sam", "ted", weight=0.2)
G.add_edge("ted", "may", weight=0.1)
G.add_edge("ted", "chris", weight=0.7)
G.add_edge("ted", "nick", weight=0.9)
G.add_edge("sam", "may", weight=0.3)

elarge = [(u, v) for (u, v, d) in G.edges(data=True) if d["weight"] > 0.5]
esmall = [(u, v) for (u, v, d) in G.edges(data=True) if d["weight"] <= 0.5]

pos = nx.circular_layout(G)  # positions for all nodes

# nodes
nx.draw_networkx_nodes(G, pos, node_size=700)

# edges
nx.draw_networkx_edges(G, pos, edgelist=elarge, width=6)
nx.draw_networkx_edges(
    G, pos, edgelist=esmall, width=6, alpha=0.5, edge_color="b", style="dashed"
)

# labels
nx.draw_networkx_labels(G, pos, font_size=20, font_family="sans-serif")

plt.axis("off")
plt.show()

Which gives the following output: enter image description here

I've been searching, but cannot find a way to hover over a node and list all its connections. For example: if I hovered over node A I would know that it is connected to B, C, and D and their respective weights. I saw this and this hover feature on Bokeh. Any ideas on how I could embed that into my code? Thank you!

Upvotes: 0

Views: 951

Answers (1)

Jiadong
Jiadong

Reputation: 2072

Please see tutorials here. Here are solutions according to your data.

import matplotlib.pyplot as plt
import networkx as nx

G = nx.Graph()

G.add_edge("a", "b", weight=0.6)
G.add_edge("a", "c", weight=0.2)
G.add_edge("c", "d", weight=0.1)
G.add_edge("c", "e", weight=0.7)
G.add_edge("c", "f", weight=0.9)
G.add_edge("a", "d", weight=0.3)

elarge = [(u, v) for (u, v, d) in G.edges(data=True) if d["weight"] > 0.5]
esmall = [(u, v) for (u, v, d) in G.edges(data=True) if d["weight"] <= 0.5]

fig, ax = plt.subplots(figsize=(7.2, 7.2))
pos = nx.circular_layout(G)  # positions for all nodes
names = np.array(list("abcdef"))

# nodes
# you have to return sc to for interaction to work
sc = nx.draw_networkx_nodes(G, pos, node_size=700)

# edges
nx.draw_networkx_edges(G, pos, edgelist=elarge, width=6)
nx.draw_networkx_edges(
    G, pos, edgelist=esmall, width=6, alpha=0.5, edge_color="b", style="dashed"
)

# labels
nx.draw_networkx_labels(G, pos, font_size=20, font_family="sans-serif")

annot = ax.annotate("", xy=(0,0), xytext=(20,20),textcoords="offset points",
                    bbox=dict(boxstyle="round", fc="w"),
                    arrowprops=dict(arrowstyle="->"))
annot.set_visible(False)

def update_annot(ind):

    pos = sc.get_offsets()[ind["ind"][0]]
    annot.xy = pos
    es = [e for e in G[names[ind["ind"]][0]]]
    text = "{}".format(es)
    annot.set_text(text)
    annot.get_bbox_patch().set_alpha(0.4)


def hover(event):
    vis = annot.get_visible()
    if event.inaxes == ax:
        cont, ind = sc.contains(event)
        if cont:
            update_annot(ind)
            annot.set_visible(True)
            fig.canvas.draw_idle()
        else:
            if vis:
                annot.set_visible(False)
                fig.canvas.draw_idle()

fig.canvas.mpl_connect("motion_notify_event", hover)

Key points:

  • return scatter points (PathCollection) for interaction to work.

enter image description here

Upvotes: 3

Related Questions