Как добавить ключ к графическому рисунку? - PullRequest
4 голосов
/ 11 апреля 2020

Я создал график, используя networkx. Когда я рисую этот график, метки узлов не помещаются (имена узлов могут быть довольно длинными), поэтому я заменил их на числовые индексы c. Проблема с этим обходным решением состоит в том, что полученный чертеж труднее интерпретировать, поскольку эти числа не имеют смысла. Это мой код:

import networkx as nx
import matplotlib.pyplot as plt

G = nx.Graph()
G.add_nodes_from(['First', 'Second', 'Third'])
G.add_edges_from([('First', 'Second'), ('First', 'Third'), ('Second', 'Third')])
name2num = {name: num + 1 for num, name in enumerate(list(G.nodes))}
H = nx.relabel_nodes(G, mapping=name2num, copy=True)

fig, (ax0, ax1) = plt.subplots(1, 2)
nx.draw(G, ax=ax0, with_labels=True)
nx.draw(H, ax=ax1, with_labels=True)

graphs
Мой вопрос: как я могу добавить ключ к рисунку справа?
Это информация Я хотел бы отобразить:

1 - First
2 - Second
3 - Third

Я пытался добавить легенду, но безрезультатно:

ax0.legend(list(name2num.values()), list(name2num.keys()))

PS : Я нашел несколько тем связано с моей проблемой. Предлагаемые решения заключаются в кодировании меток узлов разными цветами. Я бы предпочел кодировать метки узлов через числа.

Ответы [ 2 ]

1 голос
/ 11 апреля 2020

Вы можете использовать nx.draw_networkx_labels и использовать определенный словарь name2num для отображения меток на графике на второй оси. Обратите внимание, что вам не нужно создавать новый график с переименованными метками, просто нанесите его, отключив with_labels и используя вместо этого словарь:

name2num = {name: f'{num}-{name}' for num, name in enumerate(list(G.nodes), 1)}

С этим вы получите:

fig, (ax0, ax1) = plt.subplots(1, 2)

posG_renamed = nx.spring_layout(G)

nx.draw(G, ax=ax0, with_labels=True,
       node_size = 2000, node_color='lightblue')

nx.draw(G, pos=posG_renamed, ax=ax1, 
        node_size = 2000, node_color='lightgreen')

nx.draw_networkx_labels(G, posG_renamed, ax=ax1,
                        labels=name2num,
                        font_size=12)

enter image description here

1 голос
/ 11 апреля 2020

Вместо использования ax.legend вы можете разместить text box:

import networkx as nx
import matplotlib.pyplot as plt

G = nx.Graph()
G.add_nodes_from(["First", "Second", "Third"])
G.add_edges_from([("First", "Second"), ("First", "Third"), ("Second", "Third")])
name2num = {name: num + 1 for num, name in enumerate(list(G.nodes))}
H = nx.relabel_nodes(G, mapping=name2num, copy=True)

fig, (ax0, ax1) = plt.subplots(1, 2)
nx.draw(G, ax=ax0, with_labels=True)
nx.draw(H, ax=ax1, with_labels=True)


legend_text = "\n".join(f"{v} - {k}" for k, v in name2num.items())
props = dict(boxstyle="round", facecolor="w", alpha=0.5)
ax1.text(
    1.15,
    0.95,
    legend_text,
    transform=ax1.transAxes,
    fontsize=14,
    verticalalignment="top",
    bbox=props,
)

Network figure with text box legend

...