1、NetworkX
NetworkX是Python中非常强大的一款关于复杂网络的库。
下面主要 是介绍如何在PyCharm中使用NetworkX。
首先需要查看当前版本的PyCharm中是否已经包含了NetworkX的插件:
如上图所示,通过在PyCharm中的Settings -> Project->Project:Interpreter中查看是否已经加载了networkx插件,如果未加载,还需下载并安装插件。点击右上方的“+”按钮:
在上方的搜索框中输入networkx,然后点击左下角的“Install Package”按钮安装。
2、使用NetworkX建立网络
首先要在程序中引入NetworkX:
import networkx as nx
为了要已图形化的方式显示网络图,还需要引入pyplot:
import matplotlib.pyplot as plt
接下来建立简单网络:
net_grid = nx.Graph() # 新建一个无向图 net_grid
# 网络图中的所有的节点,以列表的形式存储
list_net_nodes = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
# 网络图中的所有的边,以列表的形式存储,由于是无向图,可以自动忽略掉重读的边
list_net_edges = [(1, 3), (3, 5), (5, 4), (4, 2), (2, 6),
(5, 7), (5, 8), (8, 6),
(7, 9), (8, 9), (6, 10),
(9, 11), (10, 12), (10, 13),
(11, 14), (12, 14), (12, 15),
(14, 16), (15, 16), (15, 17),
(16, 18), (17, 19),
(18, 20), (19, 20)]
# 在网络图中添加节点,直接从节点列表中读取所有的节点
net_grid.add_nodes_from(list_net_nodes)
# 在网络中添加边,直接从边列表中读取所有的边
net_grid.add_edges_from(list_net_edges)
# 画网络图
nx.draw(net_grid, with_labels=True)
# 显示
plt.show()
下图为所创建的网络图:
networkx会自动画出生成的网络图,但是画出的网络图是随机的,而且很多情况下我们画网络图是为了模拟真实的网络场景,所以需要在画网络图时能够有具体的位置信息,接下来介绍如何在生成的网络中添加位置信息。
3、使用NetworkX建立带有坐标(位置信息)的网络
为了建立带有位置信息的网络,会使用以下的API:
nx.draw_networkx_nodes() # 画节点
nx.draw_networkx_edges() # 画边
nx.draw_networkx_labels()# 画标签
函数原型如下所示:
draw_networkx_nodes(
G, # 建立的网络图
pos, # 位置信息。以字典的形式存储,其中字典的key为节点,value为长度为2的列表,存储位置信息。
nodelist=None, # 要画的指定的节点列表(可选参数,默认为G.nodes())
node_size=300, # 节点的大小
node_color='#1f78b4',# 节点的颜色
node_shape='o', # 节点的形状,候选列表:“so^>v<dph8”
alpha=1.0, # 节点的透明度
cmap=None,
vmin=None,
vmax=None,
ax=None,
linewidths=None,# 节点图标边框的宽度
edgecolors=None,# 节点图标边框的颜色
label=None, # 标签
**kwds)
draw_networkx_edges(
G, # 建立的网络图
pos,# 位置信息。以字典的形式存储,其中字典的key为节点,value为长度为2的列表,存储位置信息。
edgelist=None, # 网络中边的列表(可选参数,默认为G.edges())
width=1.0, # 边的宽度,默认为1
edge_color='k', # 边的颜色,
style='solid', # 边的风格,(默认solid,可选solid|dashed|dotted|dashdot)
alpha=1.0, # 边的透明度
arrowstyle='-|>',# 对于有向图,选择箭头的类型(默认为-|>)
arrowsize=10,# 对于有向图,设置箭头的大小
edge_cmap=None,
edge_vmin=None,
edge_vmax=None,
ax=None,
arrows=True,# 对于有向图,如果为True则画箭头,默认为True
label=None, # 标签
node_size=300,
nodelist=None,
node_shape="o",
connectionstyle=None,
**kwds)
draw_networkx_labels(
G, # 建立的网络图
pos,# 位置信息。以字典的形式存储,其中字典的key为节点,value为长度为2的列表,存储位置信息。
labels=None,# 标签信息。字典类型,其中字典的key为节点,value为节点的标签
font_size=12,# 标签的字体大小
font_color='k', # 标签字体的颜色
font_family='sans-serif',# 标签的字体类型
font_weight='normal',
alpha=1.0,# 标签字体的透明度
bbox=None,
ax=None,
**kwds)
示例:
import networkx as nx
import matplotlib.pyplot as plt
net_grid = nx.Graph()
# nodes
list_net_nodes = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
# edges
list_net_edges = [(1, 3), (3, 5), (5, 4), (4, 2), (2, 6),
(5, 7), (5, 8), (8, 6),
(7, 9), (8, 9), (6, 10),
(9, 11), (10, 12), (10, 13),
(11, 14), (12, 14), (12, 15),
(14, 16), (15, 16), (15, 17),
(16, 18), (17, 19),
(18, 20), (19, 20)]
# node's coordinate
dict_net_node_coordinate = {1: (1, 1),
2: (12, 1),
3: (2, 2),
4: (4, 2),
5: (3, 3),
6: (10, 3),
7: (2, 4),
8: (7, 4),
9: (4, 5),
10: (11, 5),
11: (3, 6),
12: (6, 6),
13: (10, 6),
14: (5, 7),
15: (10, 7),
16: (6, 8),
17: (11, 8),
18: (3, 9),
19: (8, 9),
20: (10, 10)}
dict_nodes_labels = dict(zip(list_net_nodes, list_net_nodes))
net_grid.add_nodes_from(list_net_nodes)
net_grid.add_edges_from(list_net_edges)
# draw network with coordinate
nx.draw_networkx_nodes(net_grid, dict_net_node_coordinate, list_net_nodes)
nx.draw_networkx_edges(net_grid, dict_net_node_coordinate, list_net_edges)
nx.draw_networkx_labels(net_grid, dict_net_node_coordinate, dict_nodes_labels)
plt.show()
在该示例中用到了zip函数,zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的对象,这样做的好处是节约了不少的内存。可以将zip后的对象按照需要转换成list、dict等结构。
生成的带有位置信息的网络图如下所示: