2015-04-20 5 views
7

Sto provando a creare un grafico con etichetta usando networkx ma sto riscontrando problemi nel riuscire a ottenere i nodi e le etichette correttamente. In breve, le etichette non si allineano sui nodi corretti e ci sono alcuni nodi che non hanno bordi quando vengono visualizzati.Visualizzazione del grafico di rete con le etichette

Prima ho creato un grafico, aggiunto nodi e bordi, quindi aggiunto etichette.

I dati grafico provengono da un oggetto pandi dataframe con due colonne, impiegato e gestore nomi:

   emp_name    mgr_name 
0  Marianne Becker     None 
1   Evan Abbott  Marianne Becker 
2    Jay Page  Marianne Becker 
3    Seth Reese  Marianne Becker 
4   Maxine Collier  Marianne Becker 

...

Ogni nodo è un nome ed i bordi sono mgr_name di emp_name rapporto .

Il mio codice grafico:

import networkx as nx 
G=nx.DiGraph() 

#set layout 
pos=nx.spring_layout(G) 

#add nodes 
G.add_nodes_from(df.emp_name) 
G.nodes() 
G.add_node('None') 

#create tuples for edges 
subset = df[['mgr_name','emp_name']] 
tuples = [tuple(x) for x in subset.values] 

#add edges 
G.add_edges_from(tuples) 
G.number_of_edges() 

#draw graph 
import matplotlib.pyplot as plt 
nx.draw(G, labels = True) 
plt.show() 

Idealmente vorrei avere una struttura ad albero con i nomi dei dipendenti come le etichette per ciascuno dei nodi.

immagine di uscita è enter image description here

+0

Qual è la risposta a 'G.number_of_edges()'? Sarebbe fantastico se potessi aggiungere un'immagine --- Non penso che tu abbia abbastanza "reputazione" per farlo, ma puoi metterlo online da qualche parte e pubblicare un link? Non riesco a vedere alcun errore evidente. – Joel

+0

Questo è stato ordinato dopo tutto? –

risposta

12

NetworkX ha una serie di funzioni per disegnare grafici, ma anche permettere il controllo fine dell'utente su tutto il processo.

draw è base e la sua docstring menzioni specificamente:

disegnare il grafico come una semplice rappresentazione senza nodeabels o EDGE etichette e utilizzando appieno matplotlib aree figura etichette di default. Vedere draw_networkx() per più disegno fatured che permette titolo, asse etichette

Le funzioni prefissate da draw_networkx seguita da edges, nodes, edge_labels e edge_nodes consentire un maggiore controllo sull'intero processo di trafilatura.

L'esempio ha funzionato correttamente quando si utilizza draw_networkx.

Inoltre, se si sta cercando un'uscita che assomiglia a un organogramma, suggerirei l'uso di graphviz tramite networkx. Graphviz's dot è ideale per questo tipo di diagrammi (per favore anche see this per punto).

In seguito, ho cercato di modificare il codice un po 'per dimostrare l'uso di entrambe le funzioni:

import networkx as nx 
import matplotlib.pyplot as plt 
import pandas 

#Build the dataset 
df = pandas.DataFrame({'emp_name':pandas.Series(['Marianne Becker', 'Evan Abbott', 'Jay Page', 'Seth Reese', 'Maxine Collier'], index=[0,1,2,3,4]), 'mgr_name':pandas.Series(['None', 'Marianne Becker', 'Marianne Becker', 'Marianne Becker', 'Marianne Becker'], index = [0,1,2,3,4])}) 

#Build the graph 
G=nx.DiGraph() 
G.add_nodes_from(df.emp_name) 
G.nodes() 
G.add_node('None') 
# 
#Over here, you are manually adding 'None' but in reality 
#your nodes are the unique entries of the concatenated 
#columns, i.e. emp_name, mgr_name. You could achieve this by 
#doing something like 
# 
#G.add_nodes_from(list(set(list(D.emp_name.values) + list(D.mgr_name.values)))) 
# 
# Which does exactly that, retrieves the contents of the two columns 
#concatenates them and then selects the unique names by turning the 
#combined list into a set. 

#Add edges 
subset = df[['mgr_name','emp_name']] 
tuples = [tuple(x) for x in subset.values] 
G.add_edges_from(tuples) 
G.number_of_edges() 

#Perform Graph Drawing 
#A star network (sort of) 
nx.draw_networkx(G) 
plt.show() 
t = raw_input() 
#A tree network (sort of) 
nx.draw_graphviz(G, prog = 'dot') 
plt.show() 

Si potrebbe anche provare a utilizzare punto di graphviz dalla riga di comando direttamente, salvando la rete NetworkX via nx.write_dot.Per fare questo:

dall'interno dello script python:

nx.write_dot(G, 'test.dot') 

Dopo questo, dalla tua (linux) riga di comando e assumendo che avete graphviz installato:

dot test.dot -Tpng>test_output.png 
feh test_output.png #Feh is just an image viewer. 
firefox test_output.png & #In case you don't have feh installed. 

Per una più tipico formato organogramma, è possibile forzare il routing del bordo ortogonale da

dot test.dot -Tpng -Gsplines=ortho>test_output.png 

Infine, ecco l'uscita ts

uscita di draw_networkx Output of <code>draw_networkx</code>

uscita di draw_graphviz Output of <code>draw_graphviz</code>

uscita di dot senza spigoli ortogonali Output of <code>dot</code> without orthogonal edges

uscita di dot con bordi ortogonali Output of <code>dot</code> with orthogonal edges

Spero che questo aiuti.