python网络实战(一文读懂Python复杂网络分析库networkx)
python网络实战(一文读懂Python复杂网络分析库networkx)节点2. Graph-无向图安装支持四种图绘制网络图基本流程
作者 | yyl424525
来源 | CSDN博客
文章目录
1. 简介
-
安装
-
支持四种图
-
绘制网络图基本流程
2. Graph-无向图
节点
边
属性
有向图和无向图互转
3. DiGraph-有向图
-
一些精美的图例子
-
环形树状图
-
权重图
-
Giant Component
-
Random Geometric Graph 随机几何图
-
节点颜色渐变
-
边的颜色渐变
-
Atlas
-
画个五角星
-
Club
-
画一个多层感知机
-
绘制一个DNN结构图
-
一些图论算法
-
最短路径
4. 问题
-
一些其他神经网络绘制工具列表
5. 参考
1 简介
networkx是一个用Python语言开发的图论与复杂网络建模工具,内置了常用的图与复杂网络分析算法,可以方便的进行复杂网络数据分析、仿真建模等工作。
利用networkx可以以标准化和非标准化的数据格式存储网络、生成多种随机网络和经典网络、分析网络结构、建立网络模型、设计新的网络算法、进行网络绘制等。
networkx支持创建简单无向图、有向图和多重图(multigraph);内置许多标准的图论算法,节点可为任意数据;支持任意的边值维度,功能丰富,简单易用。
networkx以图(graph)为基本数据结构。图既可以由程序生成,也可以来自在线数据源,还可以从文件与数据库中读取。
安装
安装的话,跟其他包的安装差不多,用的是anaconda就不用装了。其他就用pip install networkx。
查看版本:
1>>> import networkx
2>>> networkx.__version__
3'1.11'
升级
1pip install --upgrade networkx
下面配合使用的一些库,可以选择性安装:
后面可能用到pygraphviz,安装方法如下(亲测有效):
1sudo apt-get install graphviz
2sudo apt-get install graphviz libgraphviz-dev pkg-config
3sudo apt-get install python-pip python-virtualenv
4pip install pygraphviz
windows的安装参考这篇博客:https://blog.csdn.net/fadai1993/article/details/82491657#2____linux_9
安装cv2:
1pip install opencv-python #安装非常慢,用下面的方式,从清华源下载
2pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple opencv-python
支持四种图
-
Graph:无多重边无向图
-
DiGraph:无多重边有向图
-
MultiGraph:有多重边无向图
-
MultiDiGraph:有多重边有向图
空图对象的创建方式
1import networkx as nx
2G=nx.Graph
3G=nx.DiGraph
4G=nx.MultiGraph
5G=nx.MultiDiGraph
6G.clear #清空图
绘制网络图基本流程
-
导入networkx,matplotlib包
-
建立网络
-
绘制网络 nx.draw
-
建立布局 pos = nx.spring_layout美化作用
最基本画图程序
1import import networkx as nx #导入networkx包
2import matplotlib.pyplot as plt
3G = nx.random_graphs.barabasi_albert_graph(100 1) #生成一个BA无标度网络G
4nx.draw(G) #绘制网络G
5plt.savefig("ba.png") #输出方式1: 将图像存为一个png格式的图片文件
6plt.show #输出方式2: 在窗口中显示这幅图像
networkx 提供画图的函数
1draw(G,[pos ax hold])
2draw_networkx(G,[pos with_labels])
3draw_networkx_nodes(G pos [nodelist])绘制网络G的节点图
4draw_networkx_edges(G pos[edgelist])绘制网络G的边图
5draw_networkx_edge_labels(G pos[ …]) 绘制网络G的边图,边有label
6—有layout 布局画图函数的分界线—
7draw_circular(G **kwargs) Draw the graph G with a circular layout.
8draw_random(G **kwargs) Draw the graph G with a random layout.
9draw_spectral(G **kwargs)Draw the graph G with a spectral layout.
10draw_spring(G **kwargs)Draw the graph G with a spring layout.
11draw_shell(G **kwargs) Draw networkx graph with shell layout.
12draw_graphviz(G[ prog])Draw networkx graph with graphviz layout.
networkx 画图函数里的一些参数
-
pos(dictionary optional): 图像的布局,可选择参数;如果是字典元素,则节点是关键字,位置是对应的值。如果没有指明,则会是spring的布局;也可以使用其他类型的布局,具体可以查阅networkx.layout
-
arrows :布尔值,默认True; 对于有向图,如果是True则会画出箭头
-
with_labels: 节点是否带标签(默认为True)
-
ax:坐标设置,可选择参数;依照设置好的Matplotlib坐标画图
-
nodelist:一个列表,默认G.nodes; 给定节点
-
edgelist:一个列表,默认G.edges;给定边
-
node_size: 指定节点的尺寸大小(默认是300,单位未知,就是上图中那么大的点)
-
node_color: 指定节点的颜色 (默认是红色,可以用字符串简单标识颜色,例如’r’为红色,'b’为绿色等,具体可查看手册),用“数据字典”赋值的时候必须对字典取值(.values())后再赋值
-
node_shape: 节点的形状(默认是圆形,用字符串’o’标识,具体可查看手册)
-
alpha: 透明度 (默认是1.0,不透明,0为完全透明)
-
cmap:Matplotlib的颜色映射,默认None; 用来表示节点对应的强度
-
vmin vmax:浮点数,默认None;节点颜色映射尺度的最大和最小值
-
linewidths:[None|标量|一列值];图像边界的线宽
-
width: 边的宽度 (默认为1.0)
-
edge_color: 边的颜色(默认为黑色)
-
edge_cmap:Matplotlib的颜色映射,默认None; 用来表示边对应的强度
-
edge_vmin edge_vmax:浮点数,默认None;边的颜色映射尺度的最大和最小值
-
style: 边的样式(默认为实现,可选:solid|dashed|dotted dashdot)
-
labels:字典元素,默认None;文本形式的节点标签
-
font_size: 节点标签字体大小 (默认为12)
-
font_color: 节点标签字体颜色(默认为黑色)
-
node_size:节点大小
-
font_weight:字符串,默认’normal’
-
font_family:字符串,默认’sans-serif’
布局指定节点排列形式
-
circular_layout:节点在一个圆环上均匀分布
-
random_layout:节点随机分布shell_layout:节点在同心圆上分布
-
spring_layout:用Fruchterman-Reingold算法排列节点,中心放射状分布
-
spectral_layout:根据图的拉普拉斯特征向量排列节点
-
布局也可用pos参数指定,例如,nx.draw(G pos = spring_layout(G)) 这样指定了networkx上以中心放射状分布.
2 Graph-无向图
如果添加的节点和边是已经存在的,是不会报错的,NetworkX会自动忽略掉已经存在的边和节点的添加。
节点
常用函数
-
nodes(G):在图节点上返回一个迭代器
-
number_of_nodes(G):返回图中节点的数量
-
all_neighbors(graph node):返回图中节点的所有邻居
-
non_neighbors(graph node):返回图中没有邻居的节点
-
common_neighbors(G u v):返回图中两个节点的公共邻居
1import networkx as nx
2import matplotlib.pyplot as plt
3G = nx.Graph # 建立一个空的无向图G
4#增加节点
5G.add_node('a') # 添加一个节点1
6G.add_nodes_from(['b' 'c' 'd' 'e']) # 加点集合
7G.add_cycle(['f' 'g' 'h' 'j']) # 加环
8H = nx.path_graph(10) # 返回由10个节点的无向图
9G.add_nodes_from(H) # 创建一个子图H加入G
10G.add_node(H) # 直接将图作为节点
11
12nx.draw(G with_labels=True node_color='red')
13plt.show
14
15#访问节点
16print('图中所有的节点' G.nodes)
17#图中所有的节点 [0 1 2 3 'a' 'c' 'f' 7 8 9 <networkx.classes.graph.Graph object at 0x7fdf7d0d2780> 'g' 'e' 'h' 'b' 4 6 5 'j' 'd']
18
19print('图中节点的个数' G.number_of_nodes)
20#图中节点的个数 20
21
22#删除节点
23G.remove_node(1) #删除指定节点
24G.remove_nodes_from(['b' 'c' 'd' 'e']) #删除集合中的节点
边
常用函数
-
edges(G[ nbunch]):返回与nbunch中的节点相关的边的视图
-
number_of_edges(G):返回图中边的数目
-
non_edges(graph):返回图中不存在的边
1import networkx as nx
2import matplotlib.pyplot as plt
3
4#添加边方法1
5
6F = nx.Graph # 创建无向图
7F.add_edge(11 12) #一次添加一条边
8
9#添加边方法2
10e=(13 14) #e是一个元组
11F.add_edge(*e) #这是python中解包裹的过程
12
13#添加边方法3
14F.add_edges_from([(1 2) (1 3)]) #通过添加list来添加多条边
15
16H = nx.path_graph(10) #返回由10个节点的无向图
17#通过添加任何ebunch来添加边
18F.add_edges_from(H.edges) #不能写作F.add_edges_from(H)
19
20nx.draw(F with_labels=True)
21plt.show
22
23#访问边
24print('图中所有的边' F.edges)
25# 图中所有的边 [(0 1) (1 2) (1 3) (2 3) (3 4) (4 5) (5 6) (6 7) (7 8) (8 9) (11 12) (13 14)]
26
27print('图中边的个数' F.number_of_edges)
28# 图中边的个数 12
29
30
31
32#删除边
33F.remove_edge(1 2)
34F.remove_edges_from([(11 12) (13 14)])
35
36nx.draw(F with_labels=True)
37plt.show
使用邻接迭代器遍历每一条边
1import networkx as nx
2import matplotlib.pyplot as plt
3
4#快速遍历每一条边,可以使用邻接迭代器实现,对于无向图,每一条边相当于两条有向边
5FG = nx.Graph
6FG.add_weighted_edges_from([(1 2 0.125) (1 3 0.75) (2 4 1.2) (3 4 0.275)])
7for n nbrs in FG.adjacency_iter:
8 for nbr eattr in nbrs.items:
9 data = eattr['weight']
10 print('(%d %d %0.3f)' % (n nbr data))
11 # (1 2 0.125)
12 # (1 3 0.750)
13 # (2 1 0.125)
14 # (2 4 1.200)
15 # (3 1 0.750)
16 # (3 4 0.275)
17 # (4 2 1.200)
18 # (4 3 0.275)
19
20print('***********************************')
21
22#筛选weight小于0.5的边:
23FG = nx.Graph
24FG.add_weighted_edges_from([(1 2 0.125) (1 3 0.75) (2 4 1.2) (3 4 0.275)])
25for n nbrs in FG.adjacency_iter:
26 for nbr eattr in nbrs.items:
27 data = eattr['weight']
28 if data < 0.5:
29 print('(%d %d %0.3f)' % (n nbr data))
30 # (1 2 0.125)
31 # (2 1 0.125)
32 # (3 4 0.275)
33 # (4 3 0.275)
34
35print('***********************************')
36
37#一种方便的访问所有边的方法:
38for u v d in FG.edges(data = 'weight'):
39 print((u v d))
40 # (1 2 0.125)
41 # (1 3 0.75)
42 # (2 4 1.2)
43 # (3 4 0.275)
属性
属性诸如weight labels colors 或者任何对象,都可以附加到图、节点或边上。
对于每一个图、节点和边都可以在关联的属性字典中保存一个(多个)键-值对。
默认情况下这些是一个空的字典,但是可以增加或者是改变这些属性。
图的属性
1#图的属性
2
3import networkx as nx
4
5G = nx.Graph(day='Monday') #可以在创建图时分配图的属性
6print(G.graph)
7
8G.graph['day'] = 'Friday' #也可以修改已有的属性
9print(G.graph)
10
11G.graph['name'] = 'time' #可以随时添加新的属性到图中
12print(G.graph)
13
14输出:
15{'day': 'Monday'}
16{'day': 'Friday'}
17{'day': 'Friday' 'name': 'time'}
节点的属性
1#节点的属性
2import networkx as nx
3
4G = nx.Graph(day='Monday')
5G.add_node(1 index='1th') #在添加节点时分配节点属性
6# print(G.node(data=True)) #TypeError: 'dict' object is not callable
7print(G.node)
8#{1: {'index': '1th'}}
9
10
11G.node[1]['index'] = '0th' #通过G.node来添加或修改属性
12print(G.node)
13# {1: {'index': '0th'}}
14
15
16G.add_nodes_from([2 3] index='2/3th') #从集合中添加节点时分配属性
17print(G.node)
18# {1: {'index': '0th'} 2: {'index': '2/3th'} 3: {'index': '2/3th'}}
边的属性
1#边的属性
2import networkx as nx
3
4G = nx.Graph(day='manday')
5G.add_edge(1 2 weight=10) #在添加边时分配属性
6print(G.edges(data=True))
7#[(1 2 {'weight': 10})]
8
9G.add_edges_from([(1 3) (4 5)] len=22) #从集合中添加边时分配属性
10print(G.edges(data='len'))
11# [(1 2 None) (1 3 22) (4 5 22)]
12
13G.add_edges_from([(3 4 {'hight':10}) (1 4 {'high':'unknow'})])
14print(G.edges(data=True))
15# [(1 2 {'weight': 10}) (1 3 {'len': 22}) (1 4 {'high': 'unknow'}) (3 4 {'hight': 10}) (4 5 {'len': 22})]
16
17
18G[1][2]['weight'] = 100000 #通过G来添加或修改属性
19print(G.edges(data=True))
20# [(1 2 {'weight': 100000}) (1 3 {'len': 22}) (1 4 {'high': 'unknow'}) (3 4 {'hight': 10}) (4 5 {'len': 22})]
有向图和无向图互转
有向图和多重图的基本操作与无向图一致。
无向图与有向图之间可以相互转换,转化方法如下:
1#有向图转化成无向图
2
3H=DG.to_undirected
4#或者
5H=nx.Graph(DG)
6
7#无向图转化成有向图
8
9F = H.to_directed
10#或者
11F = nx.DiGraph(H)
3、DiGraph-有向图
1import networkx as nx
2import matplotlib.pyplot as plt
3
4G = nx.DiGraph
5G.add_node(1)
6G.add_node(2)
7G.add_nodes_from([3 4 5 6])
8G.add_cycle([1 2 3 4])
9G.add_edge(1 3)
10G.add_edges_from([(3 5) (3 6) (6 7)])
11nx.draw(G node_color = 'red')
12plt.savefig("youxiangtu.png")
13plt.show
1from __future__ import division
2import matplotlib.pyplot as plt
3import networkx as nx
4
5G = nx.generators.directed.random_k_out_graph(10 3 0.5)
6pos = nx.layout.spring_layout(G)
7
8node_sizes = [3 10 * i for i in range(len(G))]
9M = G.number_of_edges
10edge_colors = range(2 M 2)
11edge_alphas = [(5 i) / (M 4) for i in range(M)]
12
13nodes = nx.draw_networkx_nodes(G pos node_size=node_sizes node_color='blue')
14edges = nx.draw_networkx_edges(G pos node_size=node_sizes arrowstyle='->'
15 arrowsize=10 edge_color=edge_colors
16 edge_cmap=plt.cm.Blues width=2)
17# set alpha value for each edge
18for i in range(M):
19 edges[i].set_alpha(edge_alphas[i])
20
21ax = plt.gca
22ax.set_axis_off
23plt.savefig("directed.jpg")
24plt.show
一些精美的图例子
环形树状图
1import matplotlib.pyplot as plt
2import networkx as nx
3
4try:
5 import pygraphviz
6 from networkx.drawing.nx_agraph import graphviz_layout
7except ImportError:
8 try:
9 import pydot
10 from networkx.drawing.nx_pydot import graphviz_layout
11 except ImportError:
12 raise ImportError("This example needs Graphviz and either "
13 "PyGraphviz or pydot")
14
15G = nx.balanced_tree(3 5)
16pos = graphviz_layout(G prog='twopi' args='')
17plt.figure(figsize=(8 8))
18nx.draw(G pos node_size=20 alpha=0.5 node_color="blue" with_labels=False)
19plt.axis('equal')
20plt.show
权重图
1import matplotlib.pyplot as plt
2import networkx as nx
3
4G = nx.Graph
5
6G.add_edge('a' 'b' weight=0.6)
7G.add_edge('a' 'c' weight=0.2)
8G.add_edge('c' 'd' weight=0.1)
9G.add_edge('c' 'e' weight=0.7)
10G.add_edge('c' 'f' weight=0.9)
11G.add_edge('a' 'd' weight=0.3)
12
13elarge = [(u v) for (u v d) in G.edges(data=True) if d['weight'] > 0.5]
14esmall = [(u v) for (u v d) in G.edges(data=True) if d['weight'] <= 0.5]
15
16pos = nx.spring_layout(G) # positions for all nodes
17
18# nodes
19nx.draw_networkx_nodes(G pos node_size=700)
20
21# edges
22nx.draw_networkx_edges(G pos edgelist=elarge
23 width=6)
24nx.draw_networkx_edges(G pos edgelist=esmall
25 width=6 alpha=0.5 edge_color='b' style='dashed')
26
27# labels
28nx.draw_networkx_labels(G pos font_size=20 font_family='sans-serif')
29
30plt.axis('off')
31plt.savefig("weight.jpg")
32plt.show
Giant Component
1import math
3
4import matplotlib.pyplot as plt
5import networkx as nx
6
7try:
8 import pygraphviz
9 from networkx.drawing.nx_agraph import graphviz_layout
10 layout = graphviz_layout
11except ImportError:
12 try:
13 import pydot
14 from networkx.drawing.nx_pydot import graphviz_layout
15 layout = graphviz_layout
16 except ImportError:
17 print("PyGraphviz and pydot not found;\n"
18 "drawing with spring layout;\n"
19 "will be slow.")
20 layout = nx.spring_layout
21
22n = 150 # 150 nodes
23# p value at which giant component (of size log(n) nodes) is expected
24p_giant = 1.0 / (n - 1)
25# p value at which graph is expected to become completely connected
26p_conn = math.log(n) / float(n)
27
28# the following range of p values should be close to the threshold
29pvals = [0.003 0.006 0.008 0.015]
30
31region = 220 # for pylab 2x2 subplot layout
32plt.subplots_adjust(left=0 right=1 bottom=0 top=0.95 wspace=0.01 hspace=0.01)
33for p in pvals:
34 G = nx.binomial_graph(n p)
35 pos = layout(G)
36 region = 1
37 plt.subplot(region)
38 plt.title("p = %6.3f" % (p))
39 nx.draw(G pos
40 with_labels=False
41 node_size=10
42 )
43 # identify largest connected component
44 Gcc = sorted(nx.connected_component_subgraphs(G) key=len reverse=True)
45 G0 = Gcc[0]
46 nx.draw_networkx_edges(G0 pos
47 with_labels=False
48 edge_color='r'
49 width=6.0
50 )
51 # show other connected components
52 for Gi in Gcc[1:]:
53 if len(Gi) > 1:
54 nx.draw_networkx_edges(Gi pos
55 with_labels=False
56 edge_color='r'
57 alpha=0.3
58 width=5.0
59 )
60plt.show
Random Geometric Graph 随机几何图
1import matplotlib.pyplot as plt
2import networkx as nx
3
4G = nx.random_geometric_graph(200 0.125)
5# position is stored as node attribute data for random_geometric_graph
6pos = nx.get_node_attributes(G 'pos')
7
8# find node near center (0.5 0.5)
9dmin = 1
10ncenter = 0
11for n in pos:
12 x y = pos[n]
13 d = (x - 0.5)**2 (y - 0.5)**2
14 if d < dmin:
15 ncenter = n
16 dmin = d
17
18# color by path length from node near center
19p = dict(nx.single_source_shortest_path_length(G ncenter))
20
21plt.figure(figsize=(8 8))
22nx.draw_networkx_edges(G pos nodelist=[ncenter] alpha=0.4)
23nx.draw_networkx_nodes(G pos nodelist=list(p.keys)
24 node_size=80
25 node_color=list(p.values)
26 cmap=plt.cm.Reds_r)
27
28plt.xlim(-0.05 1.05)
29plt.ylim(-0.05 1.05)
30#plt.axis('off')
31plt.show
节点颜色渐变
1import networkx as nx
2import matplotlib.pyplot as plt
3G = nx.cycle_graph(24)
4pos = nx.spring_layout(G iterations=200)
5nx.draw(G pos node_color=range(24) node_size=800 cmap=plt.cm.Blues)
6plt.savefig("node.jpg")
7plt.show
边的颜色渐变
1import matplotlib.pyplot as plt
2import networkx as nx
3
4G = nx.star_graph(20)
5pos = nx.spring_layout(G) #布局为中心放射状
6colors = range(20)
7nx.draw(G pos node_color='#A0CBE2' edge_color=colors
8 width=4 edge_cmap=plt.cm.Blues with_labels=False)
9plt.show
Atlas
1import random
2
3try:
4 import pygraphviz
5 from networkx.drawing.nx_agraph import graphviz_layout
6except ImportError:
7 try:
8 import pydot
9 from networkx.drawing.nx_pydot import graphviz_layout
10 except ImportError:
11 raise ImportError("This example needs Graphviz and either "
12 "PyGraphviz or pydot.")
13
14import matplotlib.pyplot as plt
15
16import networkx as nx
17from networkx.algorithms.isomorphism.isomorph import graph_could_be_isomorphic as isomorphic
18from networkx.generators.atlas import graph_atlas_g
19
20
21 def atlas6:
22 """ Return the atlas of all connected graphs of 6 nodes or less.
23 Attempt to check for isomorphisms and remove.
24 """
25
26 Atlas = graph_atlas_g[0:208] # 208
27 # remove isolated nodes only connected graphs are left
28 U = nx.Graph # graph for union of all graphs in atlas
29 for G in Atlas:
30 zerodegree = [n for n in G if G.degree(n) == 0]
31 for n in zerodegree:
32 G.remove_node(n)
33 U = nx.disjoint_union(U G)
34
35 # iterator of graphs of all connected components
36 C = (U.subgraph(c) for c in nx.connected_components(U))
37
38 UU = nx.Graph
39 # do quick isomorphic-like check not a true isomorphism checker
40 nlist = # list of nonisomorphic graphs
41 for G in C:
42 # check against all nonisomorphic graphs so far
43 if not iso(G nlist):
44 nlist.append(G)
45 UU = nx.disjoint_union(UU G) # union the nonisomorphic graphs
46 return UU
47
48
49 def iso(G1 glist):
50 """Quick and dirty nonisomorphism checker used to check isomorphisms."""
51 for G2 in glist:
52 if isomorphic(G1 G2):
53 return True
54 return False
55
56
57if __name__ == '__main__':
58 G = atlas6
59
60 print("graph has %d nodes with %d edges"
61 % (nx.number_of_nodes(G) nx.number_of_edges(G)))
62 print(nx.number_connected_components(G) "connected components")
63
64 plt.figure(1 figsize=(8 8))
65 # layout graphs with positions using graphviz neato
66 pos = graphviz_layout(G prog="neato")
67 # color nodes the same in each connected subgraph
68 C = (G.subgraph(c) for c in nx.connected_components(G))
69 for g in C:
70 c = [random.random()] * nx.number_of_nodes(g) # random color...
71 nx.draw(g
72 pos
73 node_size=40
74 node_color=c
75 vmin=0.0
76 vmax=1.0
77 with_labels=False
78 )
79 plt.show
画个五角星
1import networkx as nx
2import matplotlib.pyplot as plt
3#画图!
4G=nx.Graph
5G.add_node(1)
6G.add_nodes_from([2 3 4 5])
7for i in range(5):
8 for j in range(i):
9 if (abs(i-j) not in (1 4)):
10 G.add_edge(i 1 j 1)
11nx.draw(G
12 with_labels=True #这个选项让节点有名称
13 edge_color='b' # b stands for blue!
14 pos=nx.circular_layout(G) # 这个是选项选择点的排列方式,具体可以用 help(nx.drawing.layout) 查看
15 # 主要有spring_layout (default) random_layout circle_layout shell_layout
16 # 这里是环形排布,还有随机排列等其他方式
17 node_color='r' # r = red
18 node_size=1000 # 节点大小
19 width=3 # 边的宽度
20 )
21plt.savefig("star.jpg")
22plt.show
Club
1import matplotlib.pyplot as plt
2import networkx as nx
3import networkx.algorithms.bipartite as bipartite
4
5G = nx.davis_southern_women_graph
6women = G.graph['top']
7clubs = G.graph['bottom']
8
9print("Biadjacency matrix")
10print(bipartite.biadjacency_matrix(G women clubs))
11
12# project bipartite graph onto women nodes
13W = bipartite.projected_graph(G women)
14print('')
15print("#Friends Member")
16for w in women:
17 print('%d %s' % (W.degree(w) w))
18
19# project bipartite graph onto women nodes keeping number of co-occurence
20# the degree computed is weighted and counts the total number of shared contacts
21W = bipartite.weighted_projected_graph(G women)
22print('')
23print("#Friend meetings Member")
24for w in women:
25 print('%d %s' % (W.degree(w weight='weight') w))
26
27nx.draw(G node_color="red")
28plt.savefig("club.jpg")
29plt.show
画一个多层感知机
1import matplotlib.pyplot as plt
2import networkx as nx
3left right bottom top layer_sizes = .1 .9 .1 .9 [4 7 7 2]
4# 网络离上下左右的距离
5# layter_sizes可以自己调整
6import random
7G = nx.Graph
8v_spacing = (top - bottom)/float(max(layer_sizes))
9h_spacing = (right - left)/float(len(layer_sizes) - 1)
10node_count = 0
11for i v in enumerate(layer_sizes):
12 layer_top = v_spacing*(v-1)/2. (top bottom)/2.
13 for j in range(v):
14 G.add_node(node_count pos=(left i*h_spacing layer_top - j*v_spacing))
15 node_count = 1
16# 这上面的数字调整我想了好半天,汗
17for x (left_nodes right_nodes) in enumerate(zip(layer_sizes[:-1] layer_sizes[1:])):
18 for i in range(left_nodes):
19 for j in range(right_nodes):
20 G.add_edge(i sum(layer_sizes[:x]) j sum(layer_sizes[:x 1]))
21
22pos=nx.get_node_attributes(G 'pos')
23# 把每个节点中的位置pos信息导出来
24nx.draw(G pos
25 node_color=range(node_count)
26 with_labels=True
27 node_size=200
28 edge_color=[random.random() for i in range(len(G.edges))]
29 width=3
30 cmap=plt.cm.Dark2 # matplotlib的调色板,可以搜搜,很多颜色
31 edge_cmap=plt.cm.Blues
32 )
33plt.savefig("mlp.jpg")
34plt.show
绘制一个DNN结构图
1# -*- coding:utf-8 -*-
2import networkx as nx
3import matplotlib.pyplot as plt
4
5# 创建DAG
6G = nx.DiGraph
7
8# 顶点列表
9vertex_list = ['v' str(i) for i in range(1 22)]
10# 添加顶点
11G.add_nodes_from(vertex_list)
12
13# 边列表
14edge_list = [
15 ('v1' 'v5') ('v1' 'v6') ('v1' 'v7') ('v1' 'v8') ('v1' 'v9')
16 ('v2' 'v5') ('v2' 'v6') ('v2' 'v7') ('v2' 'v8') ('v2' 'v9')
17 ('v3' 'v5') ('v3' 'v6') ('v3' 'v7') ('v3' 'v8') ('v3' 'v9')
18 ('v4' 'v5') ('v4' 'v6') ('v4' 'v7') ('v4' 'v8') ('v4' 'v9')
19 ('v5' 'v10') ('v5' 'v11') ('v5' 'v12') ('v5' 'v13') ('v5' 'v14') ('v5' 'v15')
20 ('v6' 'v10') ('v6' 'v11') ('v6' 'v12') ('v6' 'v13') ('v6' 'v14') ('v6' 'v15')
21 ('v7' 'v10') ('v7' 'v11') ('v7' 'v12') ('v7' 'v13') ('v7' 'v14') ('v7' 'v15')
22 ('v8' 'v10') ('v8' 'v11') ('v8' 'v12') ('v8' 'v13') ('v8' 'v14') ('v8' 'v15')
23 ('v9' 'v10') ('v9' 'v11') ('v9' 'v12') ('v9' 'v13') ('v9' 'v14') ('v9' 'v15')
24 ('v10' 'v16') ('v10' 'v17') ('v10' 'v18')
25 ('v11' 'v16') ('v11' 'v17') ('v11' 'v18')
26 ('v12' 'v16') ('v12' 'v17') ('v12' 'v18')
27 ('v13' 'v16') ('v13' 'v17') ('v13' 'v18')
28 ('v14' 'v16') ('v14' 'v17') ('v14' 'v18')
29 ('v15' 'v16') ('v15' 'v17') ('v15' 'v18')
30 ('v16' 'v19')
31 ('v17' 'v20')
32 ('v18' 'v21')
33 ]
34# 通过列表形式来添加边
35G.add_edges_from(edge_list)
36
37# 绘制DAG图
38plt.title('DNN for iris') #图片标题
39
40nx.draw(
41 G
42 node_color = 'red' # 顶点颜色
43 edge_color = 'black' # 边的颜色
44 with_labels = True # 显示顶点标签
45 font_size =10 # 文字大小
46 node_size =300 # 顶点大小
47 )
48# 显示图片
49plt.show
可以看到,在代码中已经设置好了这22个神经元以及它们之间的连接情况,但绘制出来的结构如却是这样的:
这显然不是想要的结果,因为各神经的连接情况不明朗,而且很多神经都挤在了一起,看不清楚。之所以出现这种情况,是因为没有给神经元设置坐标,导致每个神经元都是随机放置的。
接下来,引入坐标机制,即设置好每个神经元节点的坐标,使得它们的位置能够按照事先设置好的来放置,其Python代码如下:
1# -*- coding:utf-8 -*-
2import networkx as nx
3import matplotlib.pyplot as plt
4
5# 创建DAG
6G = nx.DiGraph
7
8# 顶点列表
9vertex_list = ['v' str(i) for i in range(1 22)]
10# 添加顶点
11G.add_nodes_from(vertex_list)
12
13# 边列表
14edge_list = [
15 ('v1' 'v5') ('v1' 'v6') ('v1' 'v7') ('v1' 'v8') ('v1' 'v9')
16 ('v2' 'v5') ('v2' 'v6') ('v2' 'v7') ('v2' 'v8') ('v2' 'v9')
17 ('v3' 'v5') ('v3' 'v6') ('v3' 'v7') ('v3' 'v8') ('v3' 'v9')
18 ('v4' 'v5') ('v4' 'v6') ('v4' 'v7') ('v4' 'v8') ('v4' 'v9')
19 ('v5' 'v10') ('v5' 'v11') ('v5' 'v12') ('v5' 'v13') ('v5' 'v14') ('v5' 'v15')
20 ('v6' 'v10') ('v6' 'v11') ('v6' 'v12') ('v6' 'v13') ('v6' 'v14') ('v6' 'v15')
21 ('v7' 'v10') ('v7' 'v11') ('v7' 'v12') ('v7' 'v13') ('v7' 'v14') ('v7' 'v15')
22 ('v8' 'v10') ('v8' 'v11') ('v8' 'v12') ('v8' 'v13') ('v8' 'v14') ('v8' 'v15')
23 ('v9' 'v10') ('v9' 'v11') ('v9' 'v12') ('v9' 'v13') ('v9' 'v14') ('v9' 'v15')
24 ('v10' 'v16') ('v10' 'v17') ('v10' 'v18')
25 ('v11' 'v16') ('v11' 'v17') ('v11' 'v18')
26 ('v12' 'v16') ('v12' 'v17') ('v12' 'v18')
27 ('v13' 'v16') ('v13' 'v17') ('v13' 'v18')
28 ('v14' 'v16') ('v14' 'v17') ('v14' 'v18')
29 ('v15' 'v16') ('v15' 'v17') ('v15' 'v18')
30 ('v16' 'v19')
31 ('v17' 'v20')
32 ('v18' 'v21')
33 ]
34# 通过列表形式来添加边
35G.add_edges_from(edge_list)
36
37# 指定绘制DAG图时每个顶点的位置
38pos = {
39 'v1':(-2 1.5)
40 'v2':(-2 0.5)
41 'v3':(-2 -0.5)
42 'v4':(-2 -1.5)
43 'v5':(-1 2)
44 'v6': (-1 1)
45 'v7':(-1 0)
46 'v8':(-1 -1)
47 'v9':(-1 -2)
48 'v10':(0 2.5)
49 'v11':(0 1.5)
50 'v12':(0 0.5)
51 'v13':(0 -0.5)
52 'v14':(0 -1.5)
53 'v15':(0 -2.5)
54 'v16':(1 1)
55 'v17':(1 0)
56 'v18':(1 -1)
57 'v19':(2 1)
58 'v20':(2 0)
59 'v21':(2 -1)
60 }
61# 绘制DAG图
62plt.title('DNN for iris') #图片标题
63plt.xlim(-2.2 2.2) #设置X轴坐标范围
64plt.ylim(-3 3) #设置Y轴坐标范围
65nx.draw(
66 G
67 pos = pos # 点的位置
68 node_color = 'red' # 顶点颜色
69 edge_color = 'black' # 边的颜色
70 with_labels = True # 显示顶点标签
71 font_size =10 # 文字大小
72 node_size =300 # 顶点大小
73 )
74# 显示图片
75plt.show
可以看到,在代码中,通过pos字典已经规定好了每个神经元节点的位置。
接下来,需要对这个框架图进行更为细致地修改,需要修改的地方为:
-
去掉神经元节点的标签;
-
添加模型层的文字注释(比如Input layer)
其中,第二步的文字注释,我们借助opencv来完成。完整的Python代码如下:
1# -*- coding:utf-8 -*-
2import cv2
3import networkx as nx
4import matplotlib.pyplot as plt
5
6# 创建DAG
7G = nx.DiGraph
8
9# 顶点列表
10vertex_list = ['v' str(i) for i in range(1 22)]
11# 添加顶点
12G.add_nodes_from(vertex_list)
13
14# 边列表
15edge_list = [
16 ('v1' 'v5') ('v1' 'v6') ('v1' 'v7') ('v1' 'v8') ('v1' 'v9')
17 ('v2' 'v5') ('v2' 'v6') ('v2' 'v7') ('v2' 'v8') ('v2' 'v9')
18 ('v3' 'v5') ('v3' 'v6') ('v3' 'v7') ('v3' 'v8') ('v3' 'v9')
19 ('v4' 'v5') ('v4' 'v6') ('v4' 'v7') ('v4' 'v8') ('v4' 'v9')
20 ('v5' 'v10') ('v5' 'v11') ('v5' 'v12') ('v5' 'v13') ('v5' 'v14') ('v5' 'v15')
21 ('v6' 'v10') ('v6' 'v11') ('v6' 'v12') ('v6' 'v13') ('v6' 'v14') ('v6' 'v15')
22 ('v7' 'v10') ('v7' 'v11') ('v7' 'v12') ('v7' 'v13') ('v7' 'v14') ('v7' 'v15')
23 ('v8' 'v10') ('v8' 'v11') ('v8' 'v12') ('v8' 'v13') ('v8' 'v14') ('v8' 'v15')
24 ('v9' 'v10') ('v9' 'v11') ('v9' 'v12') ('v9' 'v13') ('v9' 'v14') ('v9' 'v15')
25 ('v10' 'v16') ('v10' 'v17') ('v10' 'v18')
26 ('v11' 'v16') ('v11' 'v17') ('v11' 'v18')
27 ('v12' 'v16') ('v12' 'v17') ('v12' 'v18')
28 ('v13' 'v16') ('v13' 'v17') ('v13' 'v18')
29 ('v14' 'v16') ('v14' 'v17') ('v14' 'v18')
30 ('v15' 'v16') ('v15' 'v17') ('v15' 'v18')
31 ('v16' 'v19')
32 ('v17' 'v20')
33 ('v18' 'v21')
34 ]
35# 通过列表形式来添加边
36G.add_edges_from(edge_list)
37
38# 指定绘制DAG图时每个顶点的位置
39pos = {
40 'v1':(-2 1.5)
41 'v2':(-2 0.5)
42 'v3':(-2 -0.5)
43 'v4':(-2 -1.5)
44 'v5':(-1 2)
45 'v6': (-1 1)
46 'v7':(-1 0)
47 'v8':(-1 -1)
48 'v9':(-1 -2)
49 'v10':(0 2.5)
50 'v11':(0 1.5)
51 'v12':(0 0.5)
52 'v13':(0 -0.5)
53 'v14':(0 -1.5)
54 'v15':(0 -2.5)
55 'v16':(1 1)
56 'v17':(1 0)
57 'v18':(1 -1)
58 'v19':(2 1)
59 'v20':(2 0)
60 'v21':(2 -1)
61 }
62# 绘制DAG图
63plt.title('DNN for iris') #图片标题
64plt.xlim(-2.2 2.2) #设置X轴坐标范围
65plt.ylim(-3 3) #设置Y轴坐标范围
66nx.draw(
67 G
68 pos = pos # 点的位置
69 node_color = 'red' # 顶点颜色
70 edge_color = 'black' # 边的颜色
71 font_size =10 # 文字大小
72 node_size =300 # 顶点大小
73 )
74
75# 保存图片,图片大小为640*480
76plt.savefig('DNN_sketch.png')
77
78# 利用opencv模块对DNN框架添加文字注释
79
80# 读取图片
81imagepath = 'DNN_sketch.png'
82image = cv2.imread(imagepath 1)
83
84# 输入层
85cv2.rectangle(image (85 130) (120 360) (255 0 0) 2)
86cv2.putText(image "Input Layer" (15 390) 1 1.5 (0 255 0) 2 1)
87
88# 隐藏层
89cv2.rectangle(image (190 70) (360 420) (255 0 0) 2)
90cv2.putText(image "Hidden Layer" (210 450) 1 1.5 (0 255 0) 2 1)
91
92# 输出层
93cv2.rectangle(image (420 150) (460 330) (255 0 0) 2)
94cv2.putText(image "Output Layer" (380 360) 1 1.5 (0 255 0) 2 1)
95
96# sofrmax层
97cv2.rectangle(image (530 150) (570 330) (255 0 0) 2)
98cv2.putText(image "Softmax Func" (450 130) 1 1.5 (0 0 255) 2 1)
99
100# 保存修改后的图片
101cv2.imwrite('DNN.png' image)
一些图论算法
最短路径
函数调用:
1dijkstra_path(G source target weight=‘weight’) ————求最短路径
2dijkstra_path_length(G source target weight=‘weight’) ————求最短距离
3
4import networkx as nx
5import pylab
6import numpy as np
7#自定义网络
8row=np.array([0 0 0 1 2 3 6])
9col=np.array([1 2 3 4 5 6 7])
10value=np.array([1 2 1 8 1 3 5])
11
12print('生成一个空的有向图')
13G=nx.DiGraph
14print('为这个网络添加节点...')
15for i in range(0 np.size(col) 1):
16 G.add_node(i)
17print('在网络中添加带权中的边...')
18for i in range(np.size(row)):
19 G.add_weighted_edges_from([(row[i] col[i] value[i])])
20
21print('给网路设置布局...')
22pos=nx.shell_layout(G)
23print('画出网络图像:')
24nx.draw(G pos with_labels=True node_color='white' edge_color='red' node_size=400 alpha=0.5 )
25pylab.title('Self_Define Net' fontsize=15)
26pylab.show
27
28
29'''
30Shortest Path with dijkstra_path
31'''
32print('dijkstra方法寻找最短路径:')
33path=nx.dijkstra_path(G source=0 target=7)
34print('节点0到7的路径:' path)
35print('dijkstra方法寻找最短距离:')
36distance=nx.dijkstra_path_length(G source=0 target=7)
37print('节点0到7的距离为:' distance)
输出:
1生成一个空的有向图
2为这个网络添加节点...
3在网络中添加带权中的边...
4给网路设置布局...
5画出网络图像:
6dijkstra方法寻找最短路径:
7节点0到7的路径: [0 3 6 7]
8dijkstra方法寻找最短距离:
9节点0到7的距离为: 9
问题
本人在pycharm中运行下列程序:
1import networkx as nx
2import matplotlib.pyplot as plt
3
4G = nx.Graph # 建立一个空的无向图G
5G.add_node('a') # 添加一个节点1
6G.add_nodes_from(['b' 'c' 'd' 'e']) # 加点集合
7G.add_cycle(['f' 'g' 'h' 'j']) # 加环
8H = nx.path_graph(10) # 返回由10个节点挨个连接的无向图,所以有9条边
9G.add_nodes_from(H) # 创建一个子图H加入G
10G.add_node(H) # 直接将图作为节点
11
12nx.draw(G with_labels=True)
13plt.show
发现在Pycharm下使用matploylib库绘制3D图的时候,在最后需要显示图像的时候,每当输入plt.show 都会报错
1plt.show
2/yyl/Python/3.6/lib/python/site-packages/matplotlib/figure.py:1743: UserWarning: This figure includes Axes that are not compatible with tight_layout so its results might be incorrect.
3warnings.warn("This figure includes Axes that are not "
4...
5ValueError: max arg is an empty sequence
网上的解决方案:File -> Setting -> Tools -> Python Scientific中去掉对Show plots in tool window的勾选就好了
一些其他神经网络绘制工具列表上面都是一些这个网络库使用的一点总结,更多内容可以参考下面的官方链接。
参考
官方教程:https://networkx.github.io/documentation/stable/_downloads/networkx_reference.pdf
官方网站:https://networkx.github.io/documentation/latest/index.html
官方githu博客:http://networkx.github.io/
用Python的networkx绘制精美网络图:https://blog.csdn.net/qq951127336/article/details/54586869
networkx整理:https://www.cnblogs.com/minglex/p/9205160.html
Networkx使用指南:https://blog.csdn.net/Zhili_wang/article/details/89368177
论文中绘制神经网络工具汇总:https://blog.csdn.net/WZZ18191171661/article/details/87886588
networkx Cytoscape构建及可视化网络图:https://www.jianshu.com/p/f62991aa1f8a
用python graphviz/networkx画目录结构树状图:https://blog.csdn.net/XiaoPANGXia/article/details/53043664
(*本文为 AI科技大本营转载文章,转载请联系原作者)
◆
◆
2019 中国大数据技术大会(BDTC)再度来袭!豪华主席阵容及百位技术专家齐聚,15 场精选专题技术和行业论坛,超强干货 技术剖析 行业实践立体解读,深入解析热门技术在行业中的实践落地。