python聚类结果可视化_Python利⽤igraph绘制复杂⽹络聚类
(社区检测)结果图
前⾔:研究⽣期间主要做复杂⽹络聚类,也称为社区检测。临毕业前,⽼师让之前发表的论⽂⾥的算法代码C化,并写出界⾯进⾏可视化。由于之前虽然做过可视化,但基本上都是将聚类结果导⼊到pajek或者gephi这类专门的软件⾥进⾏绘制的。想要将社区检测结果实时的进⾏绘制并且要通过C\C++直接绘制,确实没有什么头绪。后来,通过浏览博客知道igaph这个包可以使⽤,由于想要熟悉下python,于是选择了Python的igraph包,⽽放弃使⽤C语⾔的igraph包。这样,我就可以将算法产⽣的聚类结果直接导⼊Python代码,并利⽤Python的igraph包进⾏⽹络划分结果的绘制。然后,再⽤C++调⽤Python代码,并将Python产⽣的聚类结果图直接加载到MFC中,这样就能实现实时地对社区检测结果进⾏绘制。
⼀. 利⽤Python进⾏⽹络聚类图的绘制
当然我们需要实现安装Python和igraph包。本⼈使⽤的系统是win7系统,安装的软件是anaconda,内含Python2.7版本,基本上需要的东西anaconda都集成好了,⼀键安装很是⽅便。
其次,我们需要安装python-igraph包。这是官⽅⽹址。直接使⽤pip安装会出现问题(Windows系统本⾝的问题),因此本⼈选⽤的⾮官⽅⽹址的安装包,见这⾥。这个⽹址在官⽹也提供了,⼀定要选对对应的
版本。Python3.6以上的版本好像并没有对应的igraph包,因此安装的时候会出现平台不⽀持的提⽰。然后在dos系统环境下pip install 安装包,即可实现igraph的安装。
系统结构图有哪两种类型接下来,我们还需要安装⽀持igraph绘制图形的Cairo库。这个库同样在上⾯提供的⾮官⽅⽹址上可以到,下载对应系统的版本,并进⾏pip安装即可。这⾥不再详细介绍。
前提⼯作做好,接下⾥进⾏⽹络社区图的绘制。如果不熟悉igraph包的使⽤,可以参见官⽹的使⽤⼿册。⾥⾯也有关于⽹络图绘制的介绍。下⾯给出相关代码:
# Python 2.7
from igraph import *
from PIL import Image
colors_type = ["yellow", "red", "green", "coral", "alice blue", "cyan", "pink",
"gray", "blue", "green yellow", "orange", "light blue", "hot pink", "light green", "gold"]
def PlotNetworks(net_file, detected_label, real_label = "Unknown Type"):
## read files
network = Graph.Read_Adjacency(net_file)
<_undirected(network)
f1 = open(detected_label)
小程序制作软件有哪些line = f1.readline()
line = line.strip()
str_line = line.split('\t')
dlabel = [int(ele) for ele in str_line]
network.vs["dlabel"] = dlabel
if(real_label != "Unknown Type"):
f2 = open(real_label)
line = f2.readline()
line = line.strip()
str_line = line.split('\t')
rlabel = [int(ele) for ele in str_line]
network.vs["rlabel"] = rlabel
# plot networks
nnodes = len(network.vs)
network.vs["name"] = [str(i+1) for i in range(nnodes)]
layout = network.layout("drl")
visual_style = {}
麦客表单登录if(nnodes < 100):
visual_style["vertex_size"] = 22
else:
visual_style["vertex_size"] = 18
visual_style["vertex_label"] = network.vs["name"]
visual_style["layout"] = layout
visual_style["bbox"] = (500,500)
visual_style["margin"] = 20
visual_style["edge_curved"] = 0.3
visual_style["vertex_color"] = [colors_type[i-1] for i in network.vs["dlabel"]]jdk环境变量配置完要重启吗
plot(network, "social_network1.png", **visual_style)
figure1 = Image.open("social_network1.png")
figure1.save("social_network1.bmp")
if(real_label != "Unknown Type"):
visual_style["vertex_color"] = [colors_type[i-1] for i in network.vs["rlabel"]]
plot(network, "social_network2.png", **visual_style)
figure2 = Image.open("social_network2.png")
figure2.save("social_network2.bmp")
代码写的稍微有些繁琐,主要是为了之后C++代码的调⽤⽅便。函数需要三个参数,均为⽂件路径名。第⼀个⽂件是复杂⽹络的邻接矩阵,我们可以使⽤Graph.Read_Adjacency()来直接读取,不过这个⽅法默认读取的是有向⽹络,⽽我使⽤的均是⽆向⽹络,所以需要使⽤_undirected()将其转换为⽆向⽹络。第⼆个⽂件为算法的聚类结果⽂件,⽂件是由1-k个整数标签表⽰社区检测结果,k表⽰⼀共检测到k个社区。第三个⽂件表⽰真实的⽹络划分结果,对于有些⽹络,我们往往并不知道真实的⽹络划分结果,这⾥是⼀个可选⽂件。
接着,绘制⽹络的可视化效果参数。使⽤字典可以直接将可视化参数设置好,这⾥我们⽤visual_style
来表⽰。相关参数均可以在上述提供的官⽅⼿册到。其中着重介绍下visual_style["layout"]这个参数,它是⼀种⽹络的布局算法,熟悉pajek软件的同学对这个参数应该也有所了解。其中“drl”是⼤图的分布式递归布局算法,常⽤的还有“kk”,“fr”等,这些都能使⾃⼰的⽹络节点布局合理,⽐较美观。由于这些参数都是⾮确定型的绘图⽅式,也就是说,每次节点的布局都会有所差异。更多参数见官⽹⼿册。
这⾥的color_style给了很多颜⾊,因为后期要绘制美国⼤学⽣⾜球队⽹络,需要⾄少12种颜⾊,这⾥Wikipedia提供了多达上百种的颜⾊,只需要将颜⾊的⾸字母⼩写即可。最后需要说明⼀下,由于我的MFC代码⾥需要调⽤bmp图像,⽽plot不能存储为bmp格式,这⾥多了⼀步将png转换为bmp格式的过程。
下⾯给出MFC界⾯绘制社区检测效果图,图像绘制如下:
1、Zachary's karate network(即跆拳道⽹络):
2、dolphin social network
3、American football network
这⾥为了突出检测图和真实图的区别,故意选择了效果⼀般时的参数。勿介意(⼿动滑稽)。。。
⼆、MFC调⽤Python代码
前⾯已经给出了绘制社区检测效果图的代码。这⾥简单介绍下怎样使⽤C++代码调⽤Python代码。这篇【博客】基本实现了vs配置使⽤
C++调⽤python代码,这⾥需要强调⼏点:第五步应该在第三步之前进⾏实施,因为我配置完第五步之后,发现原先配置好的第三步⼜变回了原始配置,所以我们可以先配置第五步再接着配置第三步;此外,由于我们安装的是anaconda,所以我们需要在anaconda的相关⽂件下到include⽬录和libs⽬录,并进⾏配置⽽⾮Python27⽬录,其他不需要改变。这样我们就可以配置好vs环境。
下⾯代码实现了C++调⽤Python代码:
void callPython(char *str1, char *str2, char *str3)
{
Py_Initialize();
PyObject *pModule = NULL;
PyObject *pFunc = NULL;
pModule = PyImport_ImportModule("PlotNetworks");
pFunc = PyObject_GetAttrString(pModule, "PlotNetworks");
PyObject *pArgs = PyTuple_New(3);
PyTuple_SetItem(pArgs, 0, Py_BuildValue("s", str1));
PyTuple_SetItem(pArgs, 1, Py_BuildValue("s", str2));
PyTuple_SetItem(pArgs, 2, Py_BuildValue("s", str3));
PyEval_CallObject(pFunc, pArgs);
Py_Finalize();
}
str1, str2, str3就是我们Python代码⾥所需要的三个⽂件,PyImport_ImportModule()调⽤的是我们的python⽂件名,下⾯的函数调
⽤“PlotNetworks”
是python代码内的函数名。这⾥的pArgs对应Python⾥的⼀个元组,下⾯的参数“s”表⽰该参数是字符串类型。通过pArgs可以实现将参数传递给pFunc。
这篇【博客】可以进⾏参考。最后,在使⽤MFC绘制⽹络图的时候,发现了⼀个问题。即当我第⼆次选择⽂件时,在点击聚类就会出现问题,提⽰显⽰
python调⽤那⼀块出现问题。了⼀些资料,发现Py_Initialize()和Py_Finalize()在⼀个程序中不能多次使⽤,原因是Py_Initialize初始化的占⽤的内存并
不能被Py_Finalize()完全释放(⼤概是这个意思)。于是我将这两个函数分开来,⼀个放在MFC窗⼝的初始化中,⼀个放在关闭窗⼝的消息函数中,最
python安装教程win7终解决了这个问题。
结束语:写这个博客的原因⼀⽅⾯为了记录下这⼏天的⼯作,另⼀⽅⾯发现⽹上写R使⽤igraph包绘制复杂⽹络图的博客较多,对于Python绘制复
html页面左侧框架杂⽹络图的很少。于是写下这⼀篇博客,希望能为研究复杂⽹络的⼩伙伴提供⼀些思路。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论