web-dev-qa-db-ja.com

NetworkXからの階層的な出力を保証する方法はありますか?

tree構造のフロー図を作成しようとしています。 networkxで代表的なグラフを作成できましたが、プロットを出力するときにtree構造を表示する方法が必要です。 matplotlib.pylabを使用してグラフをプロットしています。

here のような構造でデータを表示する必要があります。サブグラフはありませんが。

そのような構造をどのように保証できますか?

不信者の例:

Various NetworkX layouts

私はpylabとgraphvizでグラフを表示することができましたが、どちらも私が探しているツリー構造を提供していません。 networkxが提供するすべてのレイアウトを試しましたが、いずれも階層を表示しません。私は何を与えるかoptions/modeがわかりません[〜#〜] or [〜#〜 ]重みを使用する必要がある場合。どんな提案でも束になります。

@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()
65
max

有向グラフを使用する場合、Graphvizドットレイアウトは、ツリーで必要な処理を行います。これを行う方法を示す上記のソリューションに似たコードを次に示します

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

[〜#〜] updated [〜#〜]

以下は、networkx-2.0用に更新されたバージョンです(また、今後の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')

enter image description here

93
Aric

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オプションをコピーしました。 4番目の子が厳密に垂直形式ではなく上に描画される理由がわかりません。 Graphvizのオプションについて詳しく知っている人が助けになるかもしれません。

7
jterrace