2012-11-22 43 views
15

Tôi đang cố gắng vẽ/phác họa (matplotlib hoặc thư viện python khác) một mạng 2D của một ma trận khoảng cách lớn, nơi khoảng cách sẽ là các cạnh của mạng được phác thảo và dòng và cột các nút của nó.Vẽ đồ thị hoặc mạng từ ma trận khoảng cách?

DistMatrix = 
[  'a', 'b',  'c', 'd'], 
['a', 0,  0.3, 0.4, 0.7], 
['b', 0.3, 0,  0.9, 0.2], 
['c', 0.4, 0.9, 0,  0.1], 
['d', 0.7, 0.2, 0.1, 0] ] 

Tôi đang tìm cách phác thảo/vẽ mạng 2d từ ma trận khoảng cách lớn hơn: nghìn 'cột và dòng): nút' a 'được liên kết với nút' b 'bằng độ sâu cạnh 0,3, các nút 'c' và 'd' sẽ bị ràng buộc bởi độ sâu cạnh của 0,1. Các công cụ/thư viện tôi có thể sử dụng (ma trận khoảng cách có thể được chuyển đổi thành ma trận khối u) để có được phép chiếu phác họa/đồ họa của mạng như thế nào? (gấu trúc, matplotlib, igraph, ...?) và một số dẫn để làm điều đó một cách nhanh chóng (tôi sẽ không xác định chức năng tự Tkinter của tôi để làm điều đó ;-))? cảm ơn câu trả lời của bạn.

+0

Về lý thuyết, điều này có thể là không thể đối với ma trận khoảng cách nhất định. Hãy tưởng tượng ví dụ ma trận khoảng cách 4 x 4 với tất cả các mục 1. Điều này xác định đơn vị ba chiều. Không có cách nào để nhúng đồ thị này vào hai chiều không đẳng cấp. Chương trình nên làm gì trong trường hợp đó? – Turion

+0

bên phải, vì vậy không có "độ dài cạnh" nhưng "độ sâu cạnh liên kết hai nút – sol

Trả lời

21

chương trình graphvizneatocố gắng để tôn trọng độ dài cạnh. doug shows a way để khai thác sử dụng neatonetworkx như thế này:

import networkx as nx 
import numpy as np 
import string 

dt = [('len', float)] 
A = np.array([(0, 0.3, 0.4, 0.7), 
       (0.3, 0, 0.9, 0.2), 
       (0.4, 0.9, 0, 0.1), 
       (0.7, 0.2, 0.1, 0) 
       ])*10 
A = A.view(dt) 

G = nx.from_numpy_matrix(A) 
G = nx.relabel_nodes(G, dict(zip(range(len(G.nodes())),string.ascii_uppercase)))  

G = nx.drawing.nx_agraph.to_agraph(G) 

G.node_attr.update(color="red", style="filled") 
G.edge_attr.update(color="blue", width="2.0") 

G.draw('/tmp/out.png', format='png', prog='neato') 

mang

enter image description here

+0

Tôi đã thử mã bạn đề xuất, được điều chỉnh theo nhu cầu của tôi (xóa A.view) và nó không hoạt động ngay cả chỉ với 7 nút. Điều gì có thể đã đi sai? Tôi đang sử dụng graphviz 2.36. – Picarus

+1

Trường hợp này tôi lỗi '' module 'đối tượng không có thuộc tính' to_agraph''. Để sửa chữa tôi sử dụng http://stackoverflow.com/questions/35279733/what -could-cause-networkx-pygraphviz-to-work-fine-alone-nhưng-không-cùng nhau và thay vào đó sử dụng 'nx.drawing.nx_agraph.to_agraph' – kungfujam

+0

@kungfujam: Cảm ơn bạn đã cập nhật. – unutbu

14

Bạn có thể sử dụng gói mạngx, hoạt động hoàn hảo với loại sự cố này. Điều chỉnh ma trận của bạn để loại bỏ một mảng NumPy đơn giản như thế này:

DistMatrix =array([[0,  0.3, 0.4, 0.7], 
[0.3, 0,  0.9, 0.2], 
[0.4, 0.9, 0,  0.1], 
[0.7, 0.2, 0.1, 0] ]) 

sau đó nhập networkx và sử dụng nó

import networkx as nx 
G = G=nx.from_numpy_matrix(DistMatrix) 
nx.draw(G) 

nếu bạn muốn vẽ một phiên bản trọng số của đồ thị, bạn phải xác định màu sắc của mỗi cạnh (ít nhất, tôi có thể không tìm thấy một cách tự động nhiều hơn để làm điều đó):

nx.draw(G,edge_color = [ i[2]['weight'] for i in G.edges(data=True) ], edge_cmap=cm.winter)