[英]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.