2012-11-22 15 views
15

Sto provando a tracciare/disegnare (matplotlib o altra libreria python) una rete 2D di una matrice a grande distanza in cui le distanze sarebbero i bordi della rete disegnata e la linea e la colonna i suoi nodi.Disegnare un grafico o una rete da una matrice di distanze?

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

Cerco delineare/trama rete 2d da tale (più grande: migliaia di colonne e righe) matrice di distanza: nodo 'un' collegata al nodo 'b' da una profondità di 0,3 bordo, i nodi 'c' e 'd' sarebbero legati da una profondità del bordo di 0.1. Quali sono gli strumenti/le librerie che posso usare (la matrice delle distanze può essere convertita in una matrice numpy) per ottenere la proiezione grafica/schizzo di tale rete? (panda, matplotlib, igraph, ...?) e alcuni inducono a farlo velocemente (non definirei la mia funzione Tkinter per farlo ;-))? grazie per le tue risposte in arrivo.

+0

In teoria, questo potrebbe essere impossibile per certe matrici distanza. Immagina per es. una matrice a 4 x 4 distanze con tutte le voci 1. Definisce un simplex tridimensionale. Non c'è modo di incorporare questo grafico in due dimensioni in modo isometrico. Cosa dovrebbe fare il programma in questo caso? – Turion

+0

right, quindi no "lunghezza del bordo" ma "profondità del bordo che collega due nodi – sol

risposta

21

Il programma graphvizneatoprova per rispettare le lunghezze dei bordi. doug shows a way Al cablaggio neato usando networkx simili:

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

cede

enter image description here

+0

Ho provato il codice suggerito, adattato alle mie esigenze (rimuovere A.view) e non ha funzionato nemmeno per soli 7 nodi. è corretto.Che cosa potrebbe essere andato storto? Sto usando graphviz 2.36 – Picarus

+1

Questo caso mi errore l'oggetto '' module 'non ha attributo' to_agraph''. Per correggere ho usato http://stackoverflow.com/questions/35279733/what -could-causa-networkx-pygraphviz-to-work-fine-alone-but-not-together e invece usato 'nx.drawing.nx_agraph.to_agraph' – kungfujam

+0

@kungfujam: Grazie per l'aggiornamento. – unutbu

14

È possibile utilizzare il pacchetto networkx, che funziona perfettamente con questo tipo di problemi. Regolare la matrice per rimuovere un semplice array NumPy come questo:

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

quindi importare NetworkX e usarlo

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

se si vuole disegnare una versione ponderata del grafico, è necessario specificare il colore di ogni bordo (almeno, non ho potuto trovare un modo più automatizzato per farlo):

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