之前记录过基于R语言和Octave的多层网络可视化工具,但安装起来比较麻烦,发现Github上有基于Python的版本,提供了supra-adjency和多关系网络可视化,直接看:https://github.com/nkoub/multinetx
据说,安装比较简单:
pip install multinetx
我安装完了之后是这样的:
multinetx==1.0.dev0
然后美滋滋引用一下demo的代码:
##Import standard libraries
import numpy as np
import matplotlib.pyplot as plt
##Import the package MultiNetX
import multinetx as mx
##Create three Erd"os- R'enyi networks with N nodes for each layer
N = 50
g1 = mx.erdos_renyi_graph(N,0.07,seed=218)
g2 = mx.erdos_renyi_graph(N,0.07,seed=211)
g3 = mx.erdos_renyi_graph(N,0.07,seed=208)
##Define the type of interconnection between the layers
adj_block = mx.lil_matrix(np.zeros((N*3,N*3)))
adj_block[0: N, N:2*N] = np.identity(N) # L_12
adj_block[0: N,2*N:3*N] = np.identity(N) # L_13
#adj_block[N:2*N,2*N:3*N] = np.identity(N) # L_23
adj_block += adj_block.T
##Create an instance of the MultilayerGraph class
mg = mx.MultilayerGraph(list_of_layers=[g1,g2,g3],
inter_adjacency_matrix=adj_block)
mg.set_edges_weights(inter_layer_edges_weight=4)
mg.set_intra_edges_weights(layer=0,weight=1)
mg.set_intra_edges_weights(layer=1,weight=2)
mg.set_intra_edges_weights(layer=2,weight=3)
##Plot the adjacency matrix and the multiplex networks
fig = plt.figure(figsize=(15,5))
ax1 = fig.add_subplot(121)
ax1.imshow(mx.adjacency_matrix(mg,weight='weight').todense(),
origin='upper',interpolation='nearest',cmap=plt.cm.jet_r)
ax1.set_title('supra adjacency matrix')
ax2 = fig.add_subplot(122)
ax2.axis('off')
ax2.set_title('regular interconnected network')
pos = mx.get_position(mg,
mx.fruchterman_reingold_layout(mg.get_layer(0)),
layer_vertical_shift=1.4,
layer_horizontal_shift=0.0,
proj_angle=7)
mx.draw_networkx(mg,pos=pos,ax=ax2,node_size=50,with_labels=False,
edge_color=[mg[a][b]['weight'] for a,b in mg.edges()],
edge_cmap=plt.cm.jet_r)
plt.show()
报错。
pip 安装的那么顺利,竟然报错。。。
PS C:\Users\Administrator\Documents\Paper\Algorithms> python run.py
Traceback (most recent call last):
File "run.py", line 168, in <module>
testMultinetx()
File "run.py", line 113, in testMultinetx
g1 = mx.erdos_renyi_graph(N,0.07,seed=218)
AttributeError: module 'multinetx' has no attribute 'erdos_renyi_graph'
说好的小图图呢?无奈之下跳进去看看multinetx的__init__.py发现是空的。
看github上的资源也是空的,可能作者提交新版本的时候忘记了吧。。。
好在作者给出了1.0beta版的源码,下载下来,解压到python的库里,比如我的路径是这样的:
D:\Python36\Lib\site-packages\multinetx
开始运行,各种小坑。可能是我的visual studio code没有那么智能,总也不能处理好tab和空格。
看在它小巧轻便的份上原谅它了。
手动调一下几个文件,最终把调整好的给大家传一份,拿走不谢。
这回秀一下python版的多层网络绘图,虽然比MuxViz差远了,但也可以一用。
===============更新@2020-10-31 20:51:12=============
为了更好地绘制多层网络,可以采用multinetx进行建模,使用Pymnet进行可视化展示。
先说一下基本思路:multinetx的底层是实现是networkX的Graph,可以实现一个方法,将MultinetX对象转化为文件,格式示例如下:
*.edges file format:
node1 layer1 node2 layer2 weight (optional)
node1 layer1 node2 layer2 weight (optional)
e.g.,
1 1 1 1 1
1 1 2 1 1
1 1 10 1 1
1 1 12 1 1
...
然后利用pyment的读入方法读取这个刚刚生成的数据集的列,示例方法:
net = MultilayerNetwork(aspects=1,fullyInterconnected=False,directed=False)
net[i,j,s,r]=w
然后就可以用
draw_figure(
net,
...
)
绘制多层网络了,比较一下效果:大致过程:
G1 = nx.Graph()
G2 = nx.Graph()
G3 = nx.Graph()
G2.add_edges_from([(1,2),(2,3),(4,6),(4,5)])
G1.add_edges_from([(1,3),(4,5)])
G3.add_edges_from([(3,4)])
# 自定义的multinetX构造函数
M = mx.build_multilayer_graph([G1,G2,G3])
# 使用multinetx 风格绘制的多层网络
mx.show_multilayer_network(M)
# 导出为临时文件
filepath = './tmp.edges'
mx.save_edges(M, filepath)
# pyment 读入临时文件并转化为 pymnet 对象
net = mx.read_edges(filepath)
# 使用 pymnet 风格绘制多层网络
net.draw_multilayer(M)
PS: 最近有点忙,后续再更新。。。
===更新@2022-8-4 17:01:37===
def build_multilayer_graph(list_of_layers, seeds):
'''
@description: 通过多个单层网络以及种子节点构建融合后的多层网络
@param : seeds为层间连边,是一个由字典构成的列表, e.g. {(0, 0):1.0}
@return:
'''
M = MultilayerGraph(list_of_layers=list_of_layers)
# layer1nodes = list(list_of_layers[0])
# layer2nodes = list(list_of_layers[1])
num_nodes = M.get_num_nodes()
# nodes = M.get_list_of_nodes()
# multi_nodes = M.get_list_of_multinetx_nodes()
# 构建超邻接矩阵
adj_block = lil_matrix(np.zeros((num_nodes, num_nodes)))
# multi_seeds = [(n,m):seeds[n] for n in seeds for m in seeds if m != n]
for s in seeds:
# e = [multi_nodes[key] for key in s]
for r in s:
for c in s:
if r != c:
adj_block[r, c] = seeds[s]
adj_block += adj_block.T
M.set_inter_edges_weight(adj_block)
return M
参考资料: