2012-11-22 20 views
15

Próbuję wykreślić/szkicować (matplotlib lub inną bibliotekę Pythona) sieć 2D wielkiej macierzy odległości, gdzie odległości będą stanowiły krawędzie zarysowanej sieci, a linia i kolumna będą jej węzłami.Rysowanie wykresu lub sieci z macierzy odległości?

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] ] 

ja searching szkic/wykres sieci 2d z takiego (większe Tysiąc kolumn i wierszy) macierzy odległości node „A” jest połączony do węzła „b” o głębokości brzegowego 0,3, węzły "c" i "d" byłyby związane z głębokością krawędzi 0,1. Jakie narzędzia/biblioteki mogę użyć (macierz odległości można przekształcić w macierz numpy), aby uzyskać szkic/graficzną projekcję takiej sieci? (pandy, matplotlib, igraph, ...?), a niektóre z nich szybko to robią (nie zdefiniowałbym mojej funkcji Self Tkinter ;-))? dzięki za odpowiedzi przychodzące.

+0

Teoretycznie, to może być możliwe dla pewnych macierzy odległości. Wyobraź sobie np. macierz odległości 4 x 4 ze wszystkimi wpisami 1. Definiuje trójwymiarowy simpleks. Nie ma sposobu, aby osadzić ten wykres w dwóch wymiarach izometrycznie. Co powinien zrobić program w takim przypadku? – Turion

+0

w prawo, więc nie ma "długości krawędzi", ale "głębokość krawędzi, która łączy dwa węzły. – sol

Odpowiedz

21

Program graphvizneatopróbuje do przestrzegania długości krawędzi. doug shows a way wykorzystać neato pomocą networkx tak:

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

daje

enter image description here

+0

Próbowałem kodu, który sugerujesz, dostosowanego do moich potrzeb (usuń A.view) i nie zadziałało nawet dla 7 węzłów. jest poprawne.Co mogło pójść nie tak? Używam graphviz 2.36. – Picarus

+1

To przypadki mnie błąd ''moduł' obiektu nie ma atrybut" to_agraph''. Aby naprawić użyłem http://stackoverflow.com/questions/35279733/what -może spowodować-networkx-pygraphviz-do-pracy-dobrze-sam-ale-nie-razem i zamiast tego użył 'nx.drawing.nx_agraph.to_agraph' – kungfujam

+0

@kungfujam: Dzięki za aktualizację. – unutbu

14

Możesz użyć pakietu networkx, który działa idealnie z tego rodzaju problemami. Dostosuj matrycę usunąć prostą numpy tablicy tak:

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

następnie importować NetworkX i używać go

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

jeśli chcesz narysować ważoną wersję wykresu, trzeba określić kolor każdej krawędzi (przynajmniej ja nie mogę znaleźć bardziej zautomatyzowany sposób, aby to zrobić):

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