[英]Add a tooltip for graph edges using networkx and matplotlib (Python)
我在 matplotlib 中繪制了一個網絡圖,並且希望有一個工具提示,當我將鼠標懸停在邊緣上時會顯示信息。
有一個解決方案可以在懸停在節點上時生成工具提示( 在 python networkx 圖中為節點添加工具提示)。 這可以適應懸停在邊緣上嗎?
import matplotlib.pyplot as plt
import networkx as nx
G = nx.path_graph(5)
attrs = {0: {'attr1': 20, 'attr2': 'nothing'}, 1: {'attr2': 3}, 2: {'attr1': 42}, 3: {'attr3': 'hello'}, 4: {'attr1': 54, 'attr3': '33'}}
nx.set_node_attributes(G, attrs)
fig, ax = plt.subplots()
pos = nx.spring_layout(G)
nodes = nx.draw_networkx_nodes(G, pos=pos, ax=ax)
nx.draw_networkx_edges(G, pos=pos, ax=ax)
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):
node = ind["ind"][0]
xy = pos[node]
annot.xy = xy
node_attr = {'node': node}
node_attr.update(G.nodes[node])
text = '\n'.join(f'{k}: {v}' for k, v in node_attr.items())
annot.set_text(text)
def hover(event):
vis = annot.get_visible()
if event.inaxes == ax:
cont, ind = nodes.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)
plt.show()
是的,這個例子可以很容易地適應邊緣而不是節點。
首先,讓我們將屬性應用於邊緣而不是節點,:
import matplotlib.pyplot as plt
import networkx as nx
G = nx.path_graph(5)
attrs = {(0, 1): {'attr1': 20, 'attr2': 'nothing'},
(1, 2): {'attr2': 3},
(2, 3): {'attr1': 42},
(3, 4): {'attr3': 'hello'},
(4, 5): {'attr1': 54, 'attr3': '33'}}
nx.set_edge_attributes(G, attrs)
現在,當我們 plot 圖形時,我們要記錄邊的位置,而不是節點:
fig, ax = plt.subplots()
pos = nx.spring_layout(G)
nx.draw_networkx_nodes(G, pos=pos, ax=ax)
edges = nx.draw_networkx_edges(G, pos=pos, ax=ax)
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)
現在,我們只需要更改update_annot
和hover
函數來查看圖的邊緣而不是節點。 因為pos
只保存節點的位置,所以我們找到邊緣任一端的節點位置的平均值,以便找到邊緣的中點。
def update_annot(ind):
edge = list(G.edges)[ind["ind"][0]]
xy = (pos[edge[0]] + pos[edge[1]])/2
annot.xy = xy
node_attr = {'edge': edge}
node_attr.update(G.edges[edge])
text = '\n'.join(f'{k}: {v}' for k, v in node_attr.items())
annot.set_text(text)
def hover(event):
vis = annot.get_visible()
if event.inaxes == ax:
cont, ind = edges.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)
plt.show()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.