1、NetworkX

NetworkX是Python中非常强大的一款关于复杂网络的库。

python网络协议 python network_位置信息

下面主要 是介绍如何在PyCharm中使用NetworkX。

首先需要查看当前版本的PyCharm中是否已经包含了NetworkX的插件:

python网络协议 python network_python_02

 如上图所示,通过在PyCharm中的Settings -> Project->Project:Interpreter中查看是否已经加载了networkx插件,如果未加载,还需下载并安装插件。点击右上方的“+”按钮:

python网络协议 python network_python网络协议_03

在上方的搜索框中输入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()

下图为所创建的网络图:

python网络协议 python network_networkx_04

 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等结构。

python网络协议 python network_位置信息_05

 生成的带有位置信息的网络图如下所示:

python网络协议 python network_位置信息_06