簡體   English   中英

使用 networkx 和 matplotlib (Python) 為圖形邊緣添加工具提示

[英]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_annothover函數來查看圖的邊緣而不是節點。 因為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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM