Есть ли способ гарантировать иерархический вывод из NetworkX?
Я пытаюсь создать блок-схему структуры дерева. Я смог создать репрезентативные графики с помощью networkx, но мне нужно показать структуру дерева при выводе графика. Я использую matplotlib.pylab для построения графика.
Мне нужно показать данные в структуре, подобной тому, что показано здесь. Хотя у меня нет подграфов.
Как я могу гарантировать такую структуру?
Примеры неверующих:
![Various NetworkX layouts]()
Мне удалось показать графики с pylab и graphviz, но не предлагаю древовидную структуру, которую я ищу. Я пробовал каждый макет networkx, который может предложить, но ни одна из них не показывает иерархию . Я просто не знаю, что options/mode дать ему ИЛИ, если мне нужно использовать вес. Любые предложения помогут сгустком.
@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()
Ответы
Ответ 1
Если вы используете ориентированный граф, то макет Graphviz dot будет делать что-то вроде дерева с деревом. Ниже приведен код, похожий на приведенные выше решения, показывающие, как это сделать
import networkx as nx
import matplotlib.pyplot as plt
G = nx.DiGraph()
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)
# write dot file to use with graphviz
# run "dot -Tpng test.dot >test.png"
nx.write_dot(G,'test.dot')
# same layout using matplotlib with no labels
plt.title('draw_networkx')
pos=nx.graphviz_layout(G, prog='dot')
nx.draw(G, pos, with_labels=False, arrows=False)
plt.savefig('nx_test.png')
![Graphviz output]()
![NetworkX/Matplotlib output]()
ОБНОВЛЕНО
Ниже приведена версия, обновленная для networkx-2.0 (и с предстоящими стрелками networkx-2.1 networkx-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')
![введите описание изображения здесь]()
Ответ 2
Вы можете использовать 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')
Результат:
![enter image description here]()
Примечание. Я скопировал параметры graphviz из указанной выше ссылки. Я не уверен, почему четвертый ребенок нарисован сверху, а не в строго вертикальном формате. Может быть, кто-то, кто знает больше о параметрах Graphviz, может помочь с этим.