2015-05-04 7 views
6

Mit Networkx in Python, ich versuche zu visualisieren, wie verschiedene Filmkritiker gegenüber bestimmten Produktionsfirmen voreingenommen sind. Um dies in einem Diagramm zu zeigen, besteht meine Idee darin, die Position jedes Produktions-Firmen-Knotens an einem einzelnen Ort in einem Kreis zu fixieren und dann den Spring_layout-Algorithmus zu verwenden, um die verbleibenden Film-Kritiker-Knoten zu positionieren sehen Sie, wie einige Kritiker eher zu bestimmten Produktionsfirmen hingezogen werden.Fix Position der Teilmenge der Knoten in NetworkX Frühjahr Grafik

Mein Problem ist, dass ich nicht scheinen kann, um die Ausgangsposition der Produktion-Firma-Knoten zu beheben. Sicher, ich kann ihre Position fixieren, aber dann ist es nur zufällig, und ich will das nicht - ich will sie in einem Kreis. Ich kann die Position aller Knoten berechnen und danach die Position der Produktion buchungs Knoten gesetzt, aber dies schlägt den Zweck, eine spring_layout Algorithmus verwenden und ich am Ende mit etwas verrückt wie:

enter image description here

Irgendwelche Ideen, wie man das richtig macht?

Derzeit mein Code tut dies:

def get_coordinates_in_circle(n): 
    return_list = [] 
    for i in range(n): 
     theta = float(i)/n*2*3.141592654 
     x = np.cos(theta) 
     y = np.sin(theta) 
     return_list.append((x,y)) 
    return return_list 

G_pc = nx.Graph() 
G_pc.add_edges_from(edges_2212) 

fixed_nodes = [] 
for n in G_pc.nodes(): 
    if n in production_companies: 
     fixed_nodes.append(n) 

pos = nx.spring_layout(G_pc,fixed=fixed_nodes) 

circular_positions = get_coordinates_in_circle(len(dps_2211)) 
i = 0 
for p in pos.keys(): 
    if p in production_companies: 
     pos[p] = circular_positions[i] 
     i += 1 

colors = get_node_colors(G_pc, "gender") 

nx.draw_networkx_nodes(G_pc, pos, cmap=plt.get_cmap('jet'), node_color=colors, node_size=50, alpha=0.5) 
nx.draw_networkx_edges(G_pc,pos, alpha=0.01) 
plt.show() 

Antwort

7

Um einen Graphen zu erstellen und ein paar Positionen:

import networkx as nx 
G=nx.Graph() 
G.add_edges_from([(1,2),(2,3),(3,1),(1,4)]) #define G 
fixed_positions = {1:(0,0),2:(-1,2)}#dict with two of the positions set 
fixed_nodes = fixed_positions.keys() 
pos = nx.spring_layout(G,pos=fixed_positions, fixed = fixed_nodes) 
nx.draw_networkx(G,pos) 

enter image description here

Ihr Problem, dass Sie die Positionen berechnen zu sein scheint von alle Knoten, bevor Sie die Positionen der festen Knoten festlegen.

Verschieben pos = nx.spring_layout(G_pc,fixed=fixed_nodes), nachdem Sie pos[p] für die festen Knoten festgelegt, und es pos = nx.spring_layout(G_pc,pos=pos,fixed=fixed_nodes)

Die dictpos speichert die Koordinaten jedes Knotens ändern. Sie sollten einen kurzen Blick auf the documentation werfen. Insbesondere

pos: dict oder Keine optional (default = None). Anfangspositionen für Knoten als Wörterbuch mit Knoten als Schlüssel und Werte als Liste oder Tupel. Wenn keine, dann nenne zufällige Anfangspositionen.

behoben: Liste oder Keine optional (Standard = Keine). Knoten, um in der Anfangsposition fixiert zu bleiben. Liste oder Keine optional (default = None)

Sie sagen es, diese Knoten in ihrer ursprünglichen Position fixiert zu halten, aber Sie haben nicht gesagt, sie, was das Ausgangsposition sein sollte. Also würde ich glauben, dass es eine zufällige Schätzung für diese anfängliche Position erfordert, und hält es fest. Wenn ich dies teste, sieht es jedoch so aus, als ob ich auf einen Fehler stoße. Es scheint, dass, wenn ich (meine Version von) networkx zu Knoten in [1,2] als fixiert sagen, aber ich sage es nicht, was ihre Positionen sind, bekomme ich einen Fehler (am Ende dieser Antwort). Ich bin überrascht, dass Ihr Code läuft.


Für einige andere Verbesserungen an der Code-Liste Comprehensions:

def get_coordinates_in_circle(n): 
    thetas = [2*np.pi*(float(i)/n) for i in range(n)] 
    returnlist = [(np.cos(theta),np.sin(theta)) for theta in thetas] 
    return return_list 

G_pc = nx.Graph() 
G_pc.add_edges_from(edges_2212) 
circular_positions = get_coordinates_in_circle(len(dps_2211)) 
#it's not clear to me why you don't define circular_positions after 
#fixed_nodes with len(fixed_nodes) so that they are guaranteed to 
#be evenly spaced. 

fixed_nodes = [n for n in G_pc.nodes() if n in production_companies] 

pos = {} 
for i,p in enumerate(fixed_nodes): 
    pos[p] = circular_positions[i] 

colors = get_node_colors(G_pc, "gender") 
pos = nx.spring_layout(G_pc,pos=pos, fixed=fixed_nodes) 
nx.draw_networkx_nodes(G_pc, pos, cmap=plt.get_cmap('jet'), node_color=colors, node_size=50, alpha=0.5) 
nx.draw_networkx_edges(G_pc,pos, alpha=0.01) 
plt.show() 

Hier ist der Fehler, den ich sehen:

import networkx as nx 
G=nx.Graph() 
G.add_edge(1,2) 
pos = nx.spring_layout(G, fixed=[1,2]) 

--------------------------------------------------------------------------- 
UnboundLocalError       Traceback (most recent call last) 
<ipython-input-4-e9586af20cc2> in <module>() 
----> 1 pos = nx.spring_layout(G, fixed=[1,2]) 

.../networkx/drawing/layout.pyc in fruchterman_reingold_layout(G, dim, k, pos, fixed, iterations, weight, scale) 
    253   # We must adjust k by domain size for layouts that are not near 1x1 
    254   nnodes,_ = A.shape 
--> 255   k=dom_size/np.sqrt(nnodes) 
    256   pos=_fruchterman_reingold(A,dim,k,pos_arr,fixed,iterations) 
    257  if fixed is None: 

UnboundLocalError: local variable 'dom_size' referenced before assignment 
+0

Vielen Dank für Ihre Antwort. Welchen Fehler bekommst du? Für mich sieht es so aus, als würden Sie Positionen zu Pos hinzufügen, bevor Sie es deklariert haben. Und um Ihren Code-Kommentar zu adressieren, werden die Positionen gleichmäßig Leerzeichen enthalten, weil len (dps_2211) == len (fixed_nodes). Ich verstehe, warum das verwirrend ist. Aber deine Lösung funktioniert. Es stellte sich heraus, dass es wichtig war, nur "pos" zu erstellen und Positionen hinzuzufügen und dann mit der soeben erstellten "pos" zu berechnen. Danke –

+0

Sie hatten Recht, Sachen zu 'pos' hinzuzufügen, bevor Sie erklärten (ich genehmigte Ihre Änderung). Ich füge den Fehler hinzu, den ich am Ende meiner Antwort erhalten habe. – Joel