добавление всплывающей подсказки для узлов в граф python networkx - PullRequest
1 голос
/ 05 мая 2020

Я создал ориентированный граф, используя networkx.DiGraph, а затем построил его, используя networkx.draw_spring(graph), так что все узлы графа имеют некоторые детали, хранящиеся в списке словарей.

Как добавить что-то вроде " всплывающая подсказка "для просмотра этих деталей при наведении курсора мыши на каждый узел? Если это возможно, как сделать эту «подсказку» всегда видимой для всех узлов, а не только при наведении курсора?

1 Ответ

1 голос
/ 05 мая 2020

Всегда виден

Чтобы пометить все узлы, вам просто нужно использовать annotate. Примерно так

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)
nx.draw(G)

for node in G.nodes:
    xy = pos[node]
    annot.xy = xy
    node_attr = G.nodes[node]
    text = '\n'.join(f'{k}: {v}' for k, v in G.nodes[node].items())
    text = f'node {node}\n' + text
    ax.annotate(text, xy=xy)

При наведении

Вот рабочий пример получения всплывающей подсказки при наведении. Это основано на всплывающих подсказках с использованием стандартных графиков matplotlib , здесь . Я использовал draw_networkx_nodes, чтобы получить объекты, используемые для наведения и отображения всплывающих подсказок, вместо использования draw_spring. Но вы можете вручную определить позицию с помощью spring_layout.

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()

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...