复杂网络分析库NetworkX学习笔记(4):网络可视化

 科学可视化是利用计算机图形学来创建视觉图像,帮助人们理解那些采取错综复杂而又往往规模庞大的数字呈现形式的科学概念或结果。对于复杂网络研究来说,可视化技术同样重要,它有助于呈现或解释复杂网络数据和模型,进而从中发现(或许是从数据中不易发现的)各种模式、特点和关系。

在我的另一篇博文《推荐一个复杂网络可视化的网站》中,介绍了www.visualcomplexity.com这个网站,上边有大量复杂网络和复杂系统的图片,五彩缤纷,令人叹为观止。有的朋友可能会想,这些图形是否都是使用一些专业的平面设计软件制作的呢?其实,通过使用NetworkX,我们同样可以制作出精美的复杂网络图形,它提供了非常丰富的网络可视化功能。下边这幅动画就是用从NetworkX网站上下载的图片拼合而成的,感兴趣的朋友可以到http://networkx.lanl.gov/gallery.html这个地址去查看生成这些图形的源代码。  在这篇笔记中,我将简单地介绍使用NetworkX绘制复杂网络图形的基本方法。当然在这方面我也是初学,只略懂一些皮毛,希望能起到抛砖引玉的作用:)

一、基本绘图流程

在NetworkX中,绘制一个网络使用nx.draw()方法,它至少接受一个参数:即你希望绘制的网络G。实际上这个方法非常复杂,它可以指定20多个关键字参数,后边会介绍一些常用的参数,我们先从最简单的情况入手,看看下边的例子:

import networkx as nx                   #导入networkx包
import matplotlib.pyplot as plt     #导入绘图包matplotlib(需要安装,方法见第一篇笔记)
G =nx.random_graphs.barabasi_albert_graph(100,1)   #生成一个BA无标度网络G
nx.draw(G)                          #绘制网络G
plt.savefig("ba.png")           #输出方式1: 将图像存为一个png格式的图片文件
plt.show()                            #输出方式2: 在窗口中显示这幅图像

运行上述代码的结果如下: 
这样,用短短的几行代码就完成了一个最基本的网络图形绘制,而且生成了一个功能丰富的窗体。窗口左下方的工具栏可以对图像进行放大、缩小、平移、保存等操作,可以自己动手试一下。同时,在源文件的目录下还生成了一个png格式的图片文件,可以把它插入报告或论文中,是不是很方便呢?

二、运用样式

上边的代码虽然简单,但生成的图形略显单调。NetworkX提供了一系列样式参数,可以用来修饰和美化图形,达到我们想要的效果。常用的参数包括:

      - `node_size`:  指定节点的尺寸大小(默认是300,单位未知,就是上图中那么大的点)
      - `node_color`:  指定节点的颜色 (默认是红色,可以用字符串简单标识颜色,例如'r'为红色,'b'为绿色等,具体可查看手册)
      - `node_shape`:  节点的形状(默认是圆形,用字符串'o'标识,具体可查看手册)
      - `alpha`: 透明度 (默认是1.0,不透明,0为完全透明) 
      - `width`: 边的宽度 (默认为1.0)
      - `edge_color`: 边的颜色(默认为黑色)
      - `style`: 边的样式(默认为实现,可选: solid|dashed|dotted,dashdot)
      - `with_labels`: 节点是否带标签(默认为True)
      - `font_size`: 节点标签字体大小 (默认为12)
      - `font_color`: 节点标签字体颜色(默认为黑色)

灵活运用上述参数,可以绘制不同样式的网络图形,例如:nx.draw(G,node_size = 30,with_labels = False) 是绘制节点尺寸为30、不带标签的网络图。

三、运用布局

NetworkX在绘制网络图形方面提供了布局的功能,可以指定节点排列的形式。这些布局包括:

circular_layout:节点在一个圆环上均匀分布
random_layout:节点随机分布
shell_layout:节点在同心圆上分布
spring_layout: 用Fruchterman-Reingold算法排列节点(这个算法我不了解,样子类似多中心放射状)
spectral_layout:根据图的拉普拉斯特征向量排列节点?我也不是太明白

布局用pos参数指定,例如:nx.draw(G,pos = nx.circular_layout(G))。在上一篇笔记中,四个不同的模型分别是用四种布局绘制的,可以到那里去看一下效果,此处就不再重复写代码了。

另外,也可以单独为图中的每个节点指定一个位置(x、y坐标),不过比较复杂,我还没有这样做过。感兴趣的朋友可以看一下NetworkX文档中的一个例子:http://networkx.lanl.gov/examples/drawing/knuth_miles.html。


四、添加文本

用 plt.title()方法可以为图形添加一个标题,该方法接受一个字符串作为参数,fontsize参数用来指定标题的大小。例如:plt.title("BA Networks", fontsize = 20)。如果要在任意位置添加文本,则可以采用plt.text()方法。事实上这些功能(包括前边的图形保存等功能)并不是由NetworkX提供的,从包的名字上可以看出,这些绘图函数都是由matplotlib这个包提供的。NetworkX只是把与复杂网络绘图相关的功能重新包装了一下,让用户调用更方便而已。

需要补充的一点是,matplotlib并不直接支持中文文本,如果想输出中文,走正规方法还是挺麻烦的(见)。不过有聪明的网友提出了一种偷梁换柱的解决方案:换字体。只要把一个中文字体文件(ttf文件)更名为Vera.ttf,拷贝到matplotlib的字体目录中覆盖原有文件,就可以输出中文了,具体细节见http://hi.baidu.com/ucherish/blog/item/63155e52b68c90070df3e3ff.html 。

五、小结

http://networkx.lanl.gov/gallery.html上的绘图示例代码,能看懂弄清这些代码,用NetworkX绘图应该就难不住你了:) 

http://blog.sciencenet.cn/blog-404069-337865.html

相关内容推荐