2016-06-24 3 views
0

Я сделал график с networkx, содержал 70% самых взвешенных ветвей, а затем преобразован в igraph, чтобы использовать community_infomap. Ярлыки на графике очень важны. Если вы сравните график и результат community_infomap, вы увидите что-то странное. На графике очевидно, что есть 2 сообщества - сигналы 1,2 и вторая группа 3.4.5.6.7.8 НО! после инфомапа он испортил метки, он сгруппировал сигналы 3.2 и 1.4.5.6.7.8. Почему, что могло случиться? 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') 

ответ

0

Чтобы узнать, что здесь происходит, мы должны понимать поведение вершин индексации igraph в. Индексы вершин нестабильны, при делеции или добавлении вершин или ребер может произойти переиндексация. Индексы всегда идут от 0 до n-1. Если вы инициализируете график целыми кортежами, igraph рассмотрит целые числа как индексы вершин. Ваши индексы начинаются с 1, поэтому igraph представит одноэлементную вершину с индексом 0, что совершенно неправильно для вас, как это было не в вашей первоначальной сети.

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

Попытка инициализировать igraph.Graph объект, как вы делали:

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

Обратите внимание на одну вершину с индексом 0, что вы впоследствии удалены, так что все остальные вершины случилось быть переиндексированы непредсказуемым образом.

Чтобы избежать этого, инициализировать Graph объект с TupleList конструктора:

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

Теперь все выглядит так же, как и в NetworkX. Примечание: это не имеет никакого отношения к community_infomap. Если вам нужны стабильные идентификаторы для ваших вершин или ребер в igraph, сохраните их в атрибутах вершин или границ.

Смежные вопросы