Чи є спосіб гарантувати ієрархічний результат від NetworkX?


84

Я намагаюся створити блок-схему деревоподібної структури. Я зміг створити репрезентативні графіки за допомогою networkx, але мені потрібен спосіб показати деревоподібну структуру, коли я вивожу графік. Я використовую matplotlib.pylab для побудови графіку.

Мені потрібно показати дані у структурі, подібній до наведеної тут . Хоча у мене немає під графіків.

Як я можу гарантувати таку структуру?

Приклади для невіруючих:

Різні макети NetworkX

Мені вдалося показати графіки за допомогою pylab та graphviz, але жоден з них не пропонує деревоподібну структуру, яку я шукаю. Я перепробував усі макети, які може запропонувати networkx, але жоден з них не показує ієрархії . Я просто не впевнений, які параметри / режим надавати йому АБО, якщо мені потрібно використовувати ваги. Будь-які пропозиції допомогли б купу.

@jterrace:

Ось приблизний контур того, що я використовував для складання сюжетів вище. Я додав кілька міток, але крім того, це те саме.

import networkx as nx
import matplotlib.pyplot as plt
G = nx.Graph()

G.add_node("ROOT")

for i in xrange(5):
    G.add_node("Child_%i" % i)
    G.add_node("Grandchild_%i" % i)
    G.add_node("Greatgrandchild_%i" % i)

    G.add_edge("ROOT", "Child_%i" % i)
    G.add_edge("Child_%i" % i, "Grandchild_%i" % i)
    G.add_edge("Grandchild_%i" % i, "Greatgrandchild_%i" % i)

plt.title("draw_networkx")
nx.draw_networkx(G)

plt.show()

Відповіді:


116

Якщо ви використовуєте спрямований графік, то макет точок Graphviz зробить з деревом щось, як ви хочете. Ось код, схожий на наведені вище рішення, який показує, як це зробити

import networkx as nx
from networkx.drawing.nx_agraph import graphviz_layout
import matplotlib.pyplot as plt
G = nx.DiGraph()

G.add_node("ROOT")

for i in range(5):
    G.add_node("Child_%i" % i)
    G.add_node("Grandchild_%i" % i)
    G.add_node("Greatgrandchild_%i" % i)

    G.add_edge("ROOT", "Child_%i" % i)
    G.add_edge("Child_%i" % i, "Grandchild_%i" % i)
    G.add_edge("Grandchild_%i" % i, "Greatgrandchild_%i" % i)

# write dot file to use with graphviz
# run "dot -Tpng test.dot >test.png"
nx.nx_agraph.write_dot(G,'test.dot')

# same layout using matplotlib with no labels
plt.title('draw_networkx')
pos=graphviz_layout(G, prog='dot')
nx.draw(G, pos, with_labels=False, arrows=False)
plt.savefig('nx_test.png')

Висновок Graphviz

Вихід NetworkX / Matplotlib

ОНОВЛЕНО

Ось версія, оновлена ​​для networkx-2.0 (і з майбутніми мережевими 2.1 також малює стрілки).

import networkx as nx
from networkx.drawing.nx_agraph import write_dot, graphviz_layout
import matplotlib.pyplot as plt
G = nx.DiGraph()

G.add_node("ROOT")

for i in range(5):
    G.add_node("Child_%i" % i)
    G.add_node("Grandchild_%i" % i)
    G.add_node("Greatgrandchild_%i" % i)

    G.add_edge("ROOT", "Child_%i" % i)
    G.add_edge("Child_%i" % i, "Grandchild_%i" % i)
    G.add_edge("Grandchild_%i" % i, "Greatgrandchild_%i" % i)

# write dot file to use with graphviz
# run "dot -Tpng test.dot >test.png"
write_dot(G,'test.dot')

# same layout using matplotlib with no labels
plt.title('draw_networkx')
pos =graphviz_layout(G, prog='dot')
nx.draw(G, pos, with_labels=False, arrows=True)
plt.savefig('nx_test.png')

введіть тут опис зображення


1
Ах ха! Отже, все, що мені потрібно, це спрямований графік із макетом «крапка». Я знав, що це щось дуже маленьке. Велике спасибі Аріку!
максимум

Чи є якийсь хороший спосіб позначити вузли по порядку? Під цим я маю на увазі, я створюю графік, g = nx.full_rary_tree(2, 10)якщо надрукую отримані краї: [(0, 1), (0, 2), (1, 3), (1, 4), (2, 5), ... ]але він буде візуалізувати їх в іншому порядку ...
CodeKingPlusPlus

1
PyGrapviz працює з Python 3, і цей код буде працювати з Python 3.
Арік,

3
також якщо у вас виникають проблеми із встановленням pygraphvizзвичайними способами, спробуйтеpip install --install-option="--include-path=/usr/local/include/" --install-option="--library-path=/usr/local/lib/" pygraphviz
Rotail

2
@Rotail Це спрацювало у мене після встановлення graphviz(у моєму випадку з використанням brew install graphviz).
Шивендра

10

Ви можете скористатися pygraphviz, щоб наблизитися:

>>> import pygraphviz
>>> import networkx
>>> import networkx as nx
>>> G = nx.Graph()
>>> G.add_node("ROOT")
>>> for i in xrange(5):
...     G.add_node("Child_%i" % i)
...     G.add_node("Grandchild_%i" % i)
...     G.add_node("Greatgrandchild_%i" % i)
...     G.add_edge("ROOT", "Child_%i" % i)
...     G.add_edge("Child_%i" % i, "Grandchild_%i" % i)
...     G.add_edge("Grandchild_%i" % i, "Greatgrandchild_%i" % i)

>>> A = nx.to_agraph(G)
>>> A.layout('dot', args='-Nfontsize=10 -Nwidth=".2" -Nheight=".2" -Nmargin=0 -Gfontsize=8')
>>> A.draw('test.png')

Результат: введіть тут опис зображення

Примітка. Я скопіював параметри graphviz із посилання, яке ви розмістили вище. Я не впевнений, чому четверта дитина намальована зверху, а не у строго вертикальному форматі. Можливо, хтось, хто знає більше про можливості Graphviz, може допомогти в цьому.


Дякую. Це було саме те, що я бачив, коли пробував. Мені здається дещо дивним, чому це створило щось подібне.
максимум

5
Зверніть увагу, що у версії 1.11 networkx api змінився. to_agraphФункція в даний час знаходиться в nx.nx_agraph.to_agraph.
m00am

1
Чи є спосіб переконатись, що дитина завжди знаходиться нижче батьків?
Дрор

0

Ви можете використовувати grandalf для рішення лише для python, якщо не хочете встановлювати graphviz.

Також цей тип візуалізації називається шаруватим графічним графіком або графічним графічним малюнком у стилі Сугіями , який може відображати багато видів графіків, включаючи не дерева.

Дивіться мою відповідь на інше запитання щодо деталей та реалізації.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.