2015-04-20 6 views
7

Ich versuche, ein markiertes Diagramm mit networkx zu erstellen, habe aber Probleme, die Knoten und Beschriftungen korrekt darzustellen. Kurz gesagt, die Labels ordnen sich nicht über den richtigen Knoten an und es gibt einige Knoten, die keine Kanten haben, wenn sie angezeigt werden.Anzeigen von Netzwerkx-Graphen mit Beschriftungen

Zuerst erstellte ich ein Diagramm, fügte Knoten und Kanten hinzu und fügte dann Beschriftungen hinzu.

Die Graph Daten stammen aus einem Pandas Dataframe-Objekt mit zwei Spalten, Mitarbeiter- und Manager-Namen:

   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 

...

Jeder Knoten ist ein Name und die Kanten sind die mgr_name Beziehung emp_name .

Mein Graph Code:

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

Idealerweise würde ich eine baumartige Struktur mit Mitarbeiternamen haben als die Etiketten für jeden der Knoten.

Ausgabebild wird enter image description here

+0

Wie lautet die Antwort auf 'G.number_of_edges()'? Es wäre toll, wenn du ein Bild hinzufügen könntest - ich glaube nicht, dass du genug "Reputation" hast, um das zu tun, aber kannst du es irgendwo online stellen und einen Link posten? Ich kann keinen offensichtlichen Fehler sehen. – Joel

+0

Wurde das doch sortiert? –

Antwort

12

NetworkX eine Reihe von Funktionen Graphen zu zeichnen, sondern auch dem Benutzer erlauben, eine genaue Kontrolle über den gesamten Prozess hat.

draw ist einfach und sein docstring ausdrücklich erwähnt:

Zeichnen Sie die grafische Darstellung als eine einfache Darstellung ohne nodeabels oder Kante Etiketten und unter Verwendung der vollständigen Abbildung Matplotlib Bereiche Etiketten durch Rückstellung. Siehe draw_networkx() für weitere fatured Zeichnung, die Titel, Achse Etikett

Die Funktionen mit vorangestellten draw_networkx gefolgt von edges, nodes, edge_labels und edge_nodes erlauben eine feinere Kontrolle über den gesamten Ziehprozess ermöglicht.

Ihr Beispiel funktionierte gut, wenn Sie draw_networkx verwenden.

Darüber hinaus, wenn Sie für eine Ausgabe suchen, die einem Organogramm ähnelt, würde ich die Verwendung von graphviz über Networkx vorschlagen. Graphviz dot ist ideal für diese Art von Diagrammen (bitte auch see this für Punkt).

Im Folgenden habe ich versucht, Ihren Code leicht zu modifizieren, um die Verwendung der beiden Funktionen zu demonstrieren:

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

Sie auch direkt graphviz den Punkt mit von der Kommandozeile versuchen könnte, indem Sie Ihre NetworkX Netzwerk über Spar nx.write_dot.Um dies zu tun:

aus Ihrem Python-Skript:

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

Danach, von Ihrem (Linux) Befehlszeile und unter der Annahme, dass Sie graphviz installiert:

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. 

Für eine typische organogram-Format können Sie orthogonale Edge-Routing erzwingen, indem

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

Schließlich sind hier die outpu

ts

Ausgabe draw_networkx Output of <code>draw_networkx</code>

Ausgabe draw_graphviz Output of <code>draw_graphviz</code>

Ausgabe von dot ohne orthogonale Kanten Output of <code>dot</code> without orthogonal edges

Ausgabe von dot mit orthogonalen Kanten Output of <code>dot</code> with orthogonal edges

Hoffnung, das hilft.