2012-07-13 18 views
45

Tôi đang cố tạo sơ đồ luồng của cấu trúc cây. Tôi đã có thể tạo ra các biểu đồ đại diện với networkx, nhưng tôi cần một cách để hiển thị cấu trúc cây khi tôi xuất một lô. Tôi đang sử dụng matplotlib.pylab để vẽ đồ thị.Có cách nào để đảm bảo đầu ra phân cấp từ NetworkX không?

Tôi cần hiển thị dữ liệu trong cấu trúc tương tự như được hiển thị here. Mặc dù tôi không có biểu đồ phụ.

Làm cách nào để đảm bảo cấu trúc như vậy?

ví dụ cho những người vô tín:

Various NetworkX layouts

tôi đã có thể hiển thị các đồ thị với pylab và graphviz, nhưng không phải đề nghị cơ cấu cây tôi đang tìm kiếm. Tôi đã thử mọi networkx bố cục phải cung cấp, nhưng không có mạng nào hiển thị cấu trúc phân cấp . Tôi vừa không chắc chắn các tùy chọn /chế độ nào để cung cấp cho nó HOẶC nếu tôi cần sử dụng trọng số. Bất kỳ gợi ý nào cũng sẽ giúp ích cho bạn.

@jterrace:

Dưới đây là một phác thảo sơ bộ những gì tôi sử dụng để tạo ra các âm mưu trên. Tôi đã thêm một số nhãn, nhưng khác hơn là nó giống nhau.

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() 

Trả lời

64

Nếu bạn sử dụng biểu đồ được hướng dẫn thì bố cục chấm Graphviz sẽ làm điều gì đó giống như bạn muốn với cây. Dưới đây là một số mã tương tự như các giải pháp trên cho thấy làm thế nào để làm điều đó

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

CẬP NHẬT

đây là một phiên bản cập nhật cho networkx-2.0 (và với các mũi tên sắp tới networkx-2.1 cũng vậy).

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

+0

Ah ha! Vì vậy, tất cả những gì tôi cần là biểu đồ có hướng với bố cục 'chấm'. Tôi biết đó là một thứ rất nhỏ. Cảm ơn rất nhiều Aric! – max

+0

Có cách nào tốt để gắn nhãn các nút tăng dần không? Ý tôi là, tôi tạo một đồ thị 'g = nx.full_rary_tree (2, 10)' Nếu tôi in các cạnh tôi nhận được: '[(0, 1), (0, 2), (1, 3), (1, 4), (2, 5), ...] 'nhưng nó sẽ hình dung chúng theo một thứ tự khác ... – CodeKingPlusPlus

+0

Bạn muốn đặt hàng nào? Xem bfs_edges() và dfs_edges(). – Aric

6

Bạn có thể sử dụng pygraphviz để có được gần gũi:

>>> 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') 

Kết quả: enter image description here

Lưu ý tôi sao chép các tùy chọn graphviz từ liên kết mà bạn đăng tải trên. Tôi không chắc tại sao đứa trẻ thứ 4 lại được vẽ trên đầu thay vì ở định dạng thẳng đứng. Có lẽ ai đó biết nhiều hơn về các tùy chọn Graphviz có thể giúp đỡ điều đó.

+0

nhờ. Đây chính xác là những gì tôi đã nhìn thấy khi tôi thử nó. Tôi tìm thấy nó hơi kỳ lạ tại sao nó tạo ra một cái gì đó như thế này. – max

+4

Lưu ý rằng trong phiên bản 1.11 của networkx api đã thay đổi. Hàm 'to_agraph' bây giờ nằm ​​trong' nx.nx_agraph.to_agraph'. – m00am

Các vấn đề liên quan