[python] NetworkX에서 계층 적 출력을 보장하는 방법이 있습니까?

트리 구조 의 흐름도를 생성하려고합니다 . 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()



답변

유 방향 그래프를 사용하는 경우 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 용으로 업데이트 된 버전입니다 (그리고 향후 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')

여기에 이미지 설명 입력


답변

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 옵션을 복사했습니다. 4 번째 자식이 엄격하게 수직 형식이 아닌 위에 그려지는 이유를 잘 모르겠습니다. Graphviz 옵션에 대해 더 많이 아는 사람이 도움을 줄 수 있습니다.


답변

graphviz를 설치하지 않으려면 python 전용 솔루션에 grandalf 를 사용할 수 있습니다 .

또한 이러한 유형의 시각화를 계층 형 그래프 그리기 또는 스기야마 스타일 그래프 그리기 라고하며 , 나무가 아닌 것을 포함하여 다양한 종류의 그래프를 표시 할 수 있습니다.

자세한 내용과 구현 은 다른 질문에 대한 내 대답을 참조하십시오 .


답변