2016-06-24 10 views
0

Ich habe einen Graph mit networkx gemacht, 70% der am meisten gewichteten Zweige behalten und dann zu igraph konvertiert, um community_infomap zu verwenden. Beschriftungen im Diagramm sind sehr wichtig. Wenn Sie Grafik und Ergebnis von community_infomap vergleichen, können Sie etwas seltsames sehen. In der Grafik ist es offensichtlich, dass es 2 Gemeinschaften gibt - Signale 1,2 und zweite Gruppe 3.4.5.6.7.8 ABER! nach infomap es versaut Etiketten, gruppierte es Signale 3.2 und 1.4.5.6.7.8. Warum, was könnte passieren? infomap graphPython iGraph - community_infomap graph

def nlargest_indices_orig(full, n): 
full = full.copy() 
x = np.zeros(n) 
y = np.zeros(n) 

for idx in range(n): 
    x[idx] = np.unravel_index(full.argmax(), full.shape)[0] 
    y[idx] = np.unravel_index(full.argmax(), full.shape)[1] 
    full[full == full.max()] = 0. 

return x, y 

labels=[1,2,3,4,5,6,7,8] 
o1 = scipy.io.loadmat('out.mat') 
X=(o1['out']) 
K=np.zeros((8,8)) 
m, n = np.shape(X) 
G = nx.Graph() 
for i in range(8): 
    for j in range(8): 
     if X[i,j]>0: 
      s=labels[i] 
      b=labels[j] 
      w=X[i,j] 
      G.add_edge(s,b,weight=w) 
B=G.edges() 
ND=len(B) 
print('Grana ukupno') 
procenat=round(0.7*ND) 
x,y=nlargest_indices_orig(X, procenat) 
s1=x 
s2=y 
for i in range(len(s2)): 
    K[s1[i],s2[i]]=X[s1[i],s2[i]] 
np.fill_diagonal(K, 0) 
F = nx.Graph() 

for i in range(8): 
    for j in range(8): 
     if K[i,j]>0: 
      s=labels[i] 
      b=labels[j] 
      w=X[i,j] 
      F.add_edge(s,b,weight=w) 
edgewidth=[] 
edgelabels={} 
pos = nx.spring_layout(F) # position the nodes by force layout 
plt.figure() 
plt.axis('off') 
print('Weighted graph') 
for (u,v,d) in F.edges(data=True): 
    print(u,v,d) 
    edgewidth.append(d['weight']) 
    edgelabels[(u,v)] = d['weight'] 
nx.draw_networkx_edges(F,pos,width=edgewidth,edge_color='r') 
nx.draw_networkx_nodes(F,pos, alpha=0.8, node_size=400,node_color='w',scale=100) 
nx.draw_networkx_labels(F,pos, font_size=12) 
pylab.savefig('Graf--odabrani-sum imf.png') 
plt.show() 
edges = F.edges() 
nodes=F.nodes() 
cg = ig.Graph(edges) 
cg.vs['label'] = labels 
singletons = cg.vs.select(_degree = 0) 
cg.delete_vertices(singletons) 
degree = 0 
community = cg.community_infomap() 
print(len(community)) 
b=ig.plot(community,'infomap-odabrani-sum imf-.png') 

Antwort

0

Um herauszufinden, was hier geschieht, müssen wir IGRAPH Vertex Indizierung Verhalten verstehen. Vertex-Indizes sind nicht stabil, Reindexing kann beim Löschen oder Hinzufügen von Scheitelpunkten oder Kanten auftreten. Die Indizes gehen immer von 0 bis n-1. Wenn Sie ein Diagramm mit Integer-Tupeln initialisieren, betrachtet igraph die Ganzzahlen als Vertex-Indizes. Ihre Indizes beginnen bei 1, also führt iigraph einen Singleton-Vertex mit dem Index 0 ein, was völlig falsch für Sie ist, da es nicht in Ihrem ursprünglichen Netzwerk war.

import igraph as ig 
import networkx as nx 
import pylab as plt 

_edges = [ 
    (1, 2), 
    (3, 4), (3, 5), (3, 6), (3, 8), 
    (4, 5), (4, 6), (4, 7), (4, 8), 
    (5, 6), (5, 7), (5, 8), 
    (6, 7), (6, 8), 
    (7, 8) 
] 

G = nx.Graph() 

for e in _edges: 
    G.add_edge(e[0], e[1], weight = 1) 

pos = nx.spring_layout(G) 
plt.figure() 
plt.axis('off') 
nx.draw_networkx_edges(G, pos, edge_color='r') 
nx.draw_networkx_nodes(G, pos, alpha=0.8, node_size=400, node_color='w', scale=100) 
nx.draw_networkx_labels(G, pos, font_size=12) 
plt.show() 
plt.savefig('nx_graph1.png') 

edges_from_nx = G.edges() 

Versuchen Sie, die igraph.Graph Objekt zu initialisieren, wie Sie tat:

g = ig.Graph(edges_from_nx) 

g.vcount() # returns 9. why? we supplied integers to igraph, 
      # what it considered as vertex indices 

'name' in g.vs.attributes() # returns False: vertices do not have names 

ig.plot(g, vertex_label = range(g.vcount())) 

graph without names

Hinweis den einzelnen Scheitelpunkt mit dem Index 0, was Sie anschließend gelöscht haben, so dass alle anderen Ecken passiert auf unvorhersehbare Weise neu indiziert werden.

Um dies zu vermeiden, initialisieren Sie das Graph Objekt mit dem TupleList Konstruktor:

g = ig.Graph.TupleList(edges_from_nx) 
g.vcount() # returns 8. this looks fine! 
'name' in g.vs.attributes() # returns True: good, labels are assigned 
          # to the `name` vertex attribute 
ig.plot(g, vertex_label = g.vs['name']) 

graph with correct labels

Jetzt ist alles das gleiche wie in NetworkX aussieht. Hinweis: Dies hat nichts mit community_infomap zu tun. Wenn Sie stabile Bezeichner für Ihre Scheitelpunkte oder Kanten in igraph wünschen, behalten Sie diese in Scheitel- oder Kantenattributen.