0

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!

1 Answer 1

3

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

Sign up to request clarification or add additional context in comments.

13 Comments

Thank you! I'm very new to python, so Im sorry for asking a stupid question but where would the return sc go?
inside update_annot(), if it solves your issue, pls accept it.
I put return sc under update_annot() but no graph pops up.
Sorry! it's working now, just realized you missed the plt.show() at the end, which is why it wasn't working. thank you :)
pls copy paste my code, it should work fine. Not returning sc in update_annot, return sc from nx.draw_networkx_nodes, whcih I have did it for you..
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.