一.networkx
1.用於圖論和復雜網絡
2.官網:http://networkx.github.io/
3.networkx常常結合numpy等數據處理相關的庫一起使用,通過matplot來可視化圖
二.繪制圖
1.創建圖

1 import networkx as nx 2 import matplotlib.pyplot as plt 3 4 G=nx.Graph()#創建空圖,無向圖 5 # G1=nx.DiGraph(e)#創建空圖,有向圖 6 # G = nx.Graph(name='my graph')#指定圖的屬性(name) 的值(my graph) 7 G.add_edges_from(([1,2],[2,3],[3,1])) 8 9 e = [(1, 2), (2, 3), (3, 4)] # 邊的列表 10 G2 = nx.Graph(e)#根據e來創建圖 11 12 F=G.to_directed()#把無向圖轉換為有向圖 13 14 #創建多圖,類MultiGraph和類MultiDiGraph允許添加相同的邊兩次,這兩條邊可能附帶不同的權值 15 # H=nx.MultiGraph(e) 16 H=nx.MultiDiGraph(e) 17 18 plt.subplot(2,2,1) 19 nx.draw(G,with_labels=True) 20 plt.subplot(2,2,2) 21 nx.draw(G2,with_labels=True) 22 plt.subplot(2,2,3) 23 nx.draw(F,with_labels=True) 24 plt.subplot(2,2,4) 25 nx.draw(H,with_labels=True) 26 27 plt.show()
2.無向圖

1 import networkx as nx 2 import matplotlib.pyplot as plt 3 4 G=nx.Graph()#創建空圖 5 6 #添加節點 7 G.add_node('a') 8 G.add_node(1) #添加單個節點 9 G.add_nodes_from([2,3,4]) #添加一些節點,容器,(可以是list, dict, set,) 10 11 #添加邊,如果點不在圖中,會自動創建點 12 G.add_edge(1,'a',weight=1.2) #添加單條邊,連接1,‘a’的邊,可以賦予邊屬性以及他的值 13 G.add_edges_from([(2,3),(3,4)])#添加一些邊(列表) 14 G.add_weighted_edges_from([(1,'a',0.1),(4,2,0.5)])#給邊賦予權重 15 16 #移除邊 17 G.remove_edge(2,4) #移除一條邊 18 G.remove_edges_from([(3,4),]) #移除一些邊 19 20 #移除節點,同時移除他對應的邊 21 G.remove_node(1) #移除單個節點 22 G.remove_nodes_from([4,]) #移除一些節點 23 24 #繪圖 25 nx.draw(G, # 圖 26 pos=nx.circular_layout(G), # 圖的布局 27 alpha=0.5, # 圖的透明度(默認1.0不透明,0完全透明) 28 29 with_labels=True, # 節點是否帶標簽 30 font_size=18, # 節點標簽字體大小 31 node_size=400, # 指定節點的尺寸大小 32 node_color='blue', # 指定節點的顏色 33 node_shape='o', # 節點的形狀 34 35 edge_color='r', # 邊的顏色 36 width=0.8, # 邊的寬度 37 style='solid', # 邊的樣式 38 39 ax=None, # Matplotlib Axes對象,可選在指定的Matplotlib軸中繪制圖形。 40 ) 41 42 plt.show()
繪圖布局
3.有向圖和無向圖的最大差別在於:有向圖中的邊是有順序的,前一個表示開始節點,后一個表示結束節點。
三.圖
數據結構
1.圖的屬性

1 #像color,label,weight或者其他Python對象的屬性都可以被設置為graph,node,edge的屬性 2 # 每個graph,node,edge都能夠包含key/value這樣的字典數據 3 import networkx as nx 4 import matplotlib.pyplot as plt 5 6 G=nx.DiGraph([(1,2),(2,3),(3,4),(1,4),(4,2)],name='my digraph',a='b') 7 #創建一個有向圖,賦予邊,點,權重,以及有向圖的屬性name的值my digraph 8 9 #屬性都可以在定義時賦予,或者通過直接賦值來添加修改 10 #圖屬性 11 print(G)#圖的名稱 12 print(G.graph)#圖的屬性,字典 13 G.graph['b']=19#賦予屬性 14 print(G.graph) 15 print('#'*60) 16 17 #節點屬性 18 print('圖的節點:',G.nodes)#列表 19 print('節點個數:',G.number_of_nodes()) 20 G.add_node('b',time='0.2') 21 print(G.node['b'])#顯示單個節點的信息 22 G.node['b']['time']=0.3#修改屬性 23 print(G.node['b']) 24 print('#'*60) 25 26 #邊屬性 27 print('圖的邊:',G.edges)#列表 28 print ('邊的個數:',G.number_of_edges()) 29 G.add_edge('a','b',weight=0.6) 30 G.add_edges_from( [ (2,3),(3,4) ], color="red") 31 G.add_edges_from( [(1,2,{"color":"blue"}),(4,5,{"weight":8})]) 32 G[1][2]["width"]=4.7#添加或修改屬性 33 print(G.get_edge_data(1, 2))#獲取某條邊的屬性 34 print('#'*60) 35 36 nx.draw(G,pos = nx.circular_layout(G),with_labels=True) 37 38 plt.show 39 -------------------------------------------------------------------------- 40 my digraph 41 {'name': 'my digraph', 'a': 'b'} 42 {'name': 'my digraph', 'a': 'b', 'b': 19} 43 ############################################################ 44 圖的節點: [1, 2, 3, 4] 45 節點個數: 4 46 {'time': '0.2'} 47 {'time': 0.3} 48 {2: {}, 4: {}} 49 ############################################################ 50 圖的邊: [(1, 2), (1, 4), (2, 3), (3, 4), (4, 2)] 51 邊的個數: 5 52 {'color': 'blue', 'width': 4.7}
2.邊和節點

1 import networkx as nx 2 import matplotlib.pyplot as plt 3 4 G=nx.DiGraph([(1,2,{'weight':10}),(2,3),(3,4),(1,4),(4,2)]) 5 6 nx.add_path(G, [0, 4,3])#在圖中添加路徑 7 8 # 對1節點進行分析 9 print(G.node[1])#節點1的信息 10 G.node[1]['time']=1#賦予節點屬性 11 print(G.node[1]) 12 print(G[1]) # 1相關的節點的信息,他的鄰居和對應的邊的屬性 13 print(G.degree(1)) # 1節點的度 14 print('#'*60) 15 16 # 對【1】【2】邊進行分析 17 print(G[1][2]) # 查看某條邊的屬性 18 G[1][2]['weight'] = 0.4 # 重新設置邊的權重 19 print(G[1][2]['weight']) # 查看邊的權重 20 G[1][2]['color'] = 'blue' # 添加屬性 21 print(G[1][2]) 22 23 nx.draw(G,pos = nx.circular_layout(G),with_labels=True) 24 25 plt.show() 26 ------------------------------------------------------------------ 27 {} 28 {'time': 1} 29 {2: {'weight': 10}, 4: {}} 30 2 31 ############################################################ 32 {'weight': 10} 33 0.4 34 {'weight': 0.4, 'color': 'blue'}
3.有向圖

1 import networkx as nx 2 import matplotlib.pyplot as plt 3 4 G=nx.DiGraph([(1,2,{'weight':10}),(2,3),(3,4),(1,4),(4,2)]) 5 print('#'*60) 6 print(G.edges)#An OutEdgeView of the DiGraph as G.edges or G.edges(). 7 print(G.out_edges)#An OutEdgeView of the DiGraph as G.edges or G.edges(). 8 print(G.in_edges)#An InEdgeView of the Graph as G.in_edges or G.in_edges() 9 print('#'*60) 10 11 print(G.degree)#圖的度 12 print(G.out_degree)#圖的出度 13 print(G.in_degree)#圖的入度 14 print('#'*60) 15 16 print(G.adj)#Graph adjacency object holding the neighbors of each node 17 print(G.neighbors(2))#節點2的鄰居 18 print(G.succ)#Graph adjacency object holding the successors of each node 19 print(G.successors(2))#節點2的后繼節點 20 print(G.pred)#Graph adjacency object holding the predecessors of each node 21 print(G.predecessors(2))#節點2的前繼節點 22 #以列表形式打印 23 print([n for n in G.neighbors(2)]) 24 print([n for n in G.successors(2)]) 25 print([n for n in G.predecessors(2)]) 26 27 nx.draw(G,pos = nx.circular_layout(G),with_labels=True) 28 29 plt.show() 30 -------------------------------------------------------- 31 ############################################################ 32 [(1, 2), (1, 4), (2, 3), (3, 4), (4, 2)] 33 [(1, 2), (1, 4), (2, 3), (3, 4), (4, 2)] 34 [(1, 2), (4, 2), (2, 3), (3, 4), (1, 4)] 35 ############################################################ 36 [(1, 2), (2, 3), (3, 2), (4, 3)] 37 [(1, 2), (2, 1), (3, 1), (4, 1)] 38 [(1, 0), (2, 2), (3, 1), (4, 2)] 39 ############################################################ 40 {1: {2: {'weight': 10}, 4: {}}, 2: {3: {}}, 3: {4: {}}, 4: {2: {}}} 41 <dict_keyiterator object at 0x0DA2BF00> 42 {1: {2: {'weight': 10}, 4: {}}, 2: {3: {}}, 3: {4: {}}, 4: {2: {}}} 43 <dict_keyiterator object at 0x0DA2BF00> 44 {1: {}, 2: {1: {'weight': 10}, 4: {}}, 3: {2: {}}, 4: {3: {}, 1: {}}} 45 <dict_keyiterator object at 0x0DA2BF00> 46 [3] 47 [3] 48 [1, 4]
4.圖的操作
Applying classic graph operations

1 import networkx as nx 2 import matplotlib.pyplot as plt 3 4 G=nx.DiGraph([(1,2,{'weight':10}),(2,1,{'weight':1}),(2,3),(3,4),(1,4),(4,2)]) 5 G2=nx.DiGraph([(1,'a'),('a','b'),(1,4)]) 6 7 H=G.subgraph([1,2,4])#產生關於節點的子圖 8 9 G3=nx.compose(H,G2)#結合兩個圖並表示兩者共同的節點 10 11 plt.subplot(221) 12 nx.draw(G,pos = nx.circular_layout(G),with_labels=True,name='G') 13 14 plt.subplot(222) 15 nx.draw(H,pos = nx.circular_layout(G),with_labels=True) 16 17 plt.subplot(223) 18 nx.draw(G2,with_labels=True) 19 20 plt.subplot(224) 21 nx.draw(G3,with_labels=True) 22 23 plt.show()
4.算法
...
四.簡單根據數據畫圖

1 import networkx as nx 2 import matplotlib.pyplot as plt 3 4 #1.導入數據: 5 # networkx支持的直接處理的數據文件格式adjlist/edgelist/gexf/gml/pickle/graphml/json/lead/yaml/graph6/sparse6/pajek/shp/ 6 #根據實際情況,把文件變為gml文件 7 G1 = nx.DiGraph() 8 with open('file.txt') as f: 9 for line in f: 10 cell = line.strip().split(',') 11 G1.add_weighted_edges_from([(cell[0],cell[1],cell[2])]) 12 nx.write_gml(G1,'file.gml')#寫網絡G進GML文件 13 14 G=nx.read_gml("file.gml") #讀取gml文件 15 # parse_gml(lines[,relael]) 從字符串中解析GML圖 16 # generate_gml(G) 以gml格式生成一個簡單條目的網絡G 17 18 print(G.nodes) 19 print(G.edges) 20 21 #2.在figure上先設置坐標 22 plt.title("圖G") 23 plt.ylabel("y") 24 plt.xlabel("x") 25 plt.xlim(-1,1) 26 plt.ylim(-1,1) 27 28 #再在坐標軸里面調節圖形大小 29 #整個figure按照X與Y軸橫豎來平均切分,以0到1之間的數值來表示 30 #axes([x,y,xs,ys]),如果不設置 31 #其中x代表在X軸的位置,y代表在Y軸的位置,xs代表在X軸上向右延展的范圍大小,yx代表在Y軸中向上延展的范圍大小 32 plt.axes([0.1, 0.1, 0.8, 0.8]) 33 34 #3.在axes中繪圖 35 nx.draw(G,pos = nx.circular_layout(G),with_labels=True,) 36 37 #4.保存圖形 38 plt.savefig("file.png")#將圖像保存到一個文件 39 40 plt.show() 41 ----------------------------------------------------- 42 ['6', '2', '5', '1', '15', '4', '3', '13', '16', '10', '7', '21', '20', '8', '17', '23', '25', '26', '28', '29', '31', '32', '34', '35', '36', '37', '44', '39', '45', '19', '46', '47', '51', '52', '53', '54', '41', '55', '57', '61', '65', '56', '66', '69', '70', '71', '72', '74', '75', '68', '64', '76', '77', '78', '60', '79', '80', '81', '62', '83', '104', '86', '87', '89', '94', '95', '96', '97', '99', '88', '101', '100', '103', '105', '106', '107', '108', '109', '110', '111', '112', '115', '114', '119', '122', '127', '129', '116', '131', '132', '133', '113', '125', '135'] 43 [('6', '2'), ('6', '5'), ('6', '4'), ('6', '7'), ('6', '114'), ('6', '32'), ('2', '21'), ('2', '20'), ('2', '4'), ('2', '54'), ('2', '132'), ('5', '1'), ('5', '6'), ('5', '7'), ('1', '15'), ('1', '5'), ('1', '32'), ('1', '34'), ('1', '17'), ('1', '31'), ('1', '13'), ('1', '20'), ('1', '54'), ('1', '56'), ('1', '71'), ('1', '74'), ('1', '78'), ('1', '68'), ('1', '81'), ('1', '101'), ('1', '119'), ('1', '2'), ('1', '76'), ('1', '23'), ('15', '97'), ('15', '70'), ('4', '3'), ('4', '26'), ('4', '6'), ('4', '31'), ('4', '57'), ('4', '61'), ('4', '66'), ('4', '72'), ('4', '41'), ('4', '87'), ('4', '39'), ('13', '16'), ('13', '10'), ('13', '17'), ('13', '29'), ('13', '1'), ('13', '34'), ('13', '7'), ('13', '54'), ('10', '1'), ('10', '6'), ('10', '21'), ('10', '8'), ('10', '25'), ('10', '2'), ('10', '3'), ('7', '5'), ('7', '34'), ('7', '6'), ('7', '29'), ('7', '13'), ('7', '3'), ('7', '36'), ('7', '53'), ('7', '55'), ('7', '20'), ('7', '28'), ('7', '76'), ('7', '19'), ('7', '89'), ('7', '109'), ('7', '111'), ('7', '100'), ('7', '47'), ('7', '122'), ('7', '116'), ('7', '133'), ('7', '54'), ('21', '2'), ('21', '1'), ('21', '10'), ('21', '8'), ('21', '3'), ('21', '36'), ('21', '39'), ('21', '7'), ('8', '1'), ('17', '3'), ('17', '23'), ('17', '28'), ('17', '13'), ('17', '20'), ('17', '1'), ('17', '81'), ('17', '39'), ('23', '17'), ('23', '19'), ('23', '32'), ('23', '20'), ('23', '69'), ('23', '7'), ('23', '108'), ('26', '4'), ('28', '7'), ('28', '69'), ('28', '132'), ('29', '13'), ('29', '51'), ('29', '52'), ('29', '7'), ('31', '4'), ('31', '1'), ('32', '6'), ('32', '1'), ('32', '23'), ('34', '7'), ('34', '1'), ('34', '13'), ('35', '6'), ('35', '1'), ('35', '65'), ('35', '69'), ('35', '70'), ('35', '79'), ('36', '37'), ('36', '46'), ('36', '41'), ('36', '21'), ('36', '7'), ('36', '78'), ('37', '36'), ('37', '44'), ('44', '37'), ('44', '39'), ('39', '45'), ('39', '7'), ('39', '44'), ('39', '21'), ('39', '69'), ('39', '17'), ('39', '4'), ('39', '109'), ('39', '114'), ('45', '39'), ('45', '53'), ('45', '54'), ('46', '36'), ('47', '1'), ('47', '7'), ('51', '29'), ('52', '29'), ('53', '45'), ('53', '7'), ('54', '45'), ('54', '1'), ('54', '62'), ('54', '129'), ('54', '13'), ('54', '2'), ('54', '7'), ('41', '36'), ('41', '75'), ('41', '60'), ('41', '4'), ('41', '83'), ('41', '104'), ('41', '86'), ('41', '89'), ('41', '70'), ('41', '105'), ('41', '110'), ('41', '68'), ('41', '64'), ('55', '7'), ('57', '4'), ('57', '110'), ('61', '4'), ('61', '20'), ('61', '2'), ('61', '77'), ('65', '35'), ('56', '1'), ('66', '4'), ('69', '39'), ('69', '35'), ('69', '23'), ('69', '28'), ('69', '62'), ('69', '81'), ('69', '99'), ('70', '95'), ('70', '41'), ('70', '35'), ('70', '96'), ('70', '15'), ('71', '1'), ('72', '4'), ('74', '1'), ('68', '64'), ('68', '1'), ('68', '97'), ('68', '41'), ('64', '68'), ('64', '80'), ('64', '94'), ('64', '112'), ('64', '41'), ('76', '7'), ('76', '1'), ('77', '39'), ('77', '15'), ('77', '6'), ('77', '1'), ('77', '23'), ('77', '28'), ('77', '115'), ('77', '112'), ('77', '131'), ('77', '61'), ('78', '1'), ('78', '60'), ('78', '36'), ('60', '41'), ('60', '78'), ('60', '87'), ('60', '108'), ('60', '112'), ('60', '56'), ('79', '35'), ('80', '25'), ('81', '17'), ('81', '69'), ('81', '1'), ('81', '107'), ('62', '69'), ('62', '54'), ('83', '41'), ('104', '41'), ('104', '108'), ('86', '41'), ('87', '4'), ('87', '60'), ('89', '41'), ('89', '7'), ('94', '64'), ('95', '70'), ('96', '70'), ('96', '106'), ('96', '107'), ('96', '15'), ('97', '15'), ('97', '68'), ('99', '69'), ('88', '7'), ('101', '1'), ('101', '103'), ('100', '101'), ('100', '60'), ('100', '1'), ('100', '7'), ('105', '41'), ('106', '96'), ('107', '81'), ('107', '96'), ('108', '60'), ('108', '23'), ('108', '104'), ('109', '7'), ('109', '39'), ('110', '57'), ('110', '41'), ('111', '7'), ('112', '64'), ('112', '77'), ('112', '115'), ('112', '60'), ('115', '77'), ('114', '39'), ('119', '1'), ('119', '127'), ('119', '25'), ('122', '7'), ('127', '119'), ('127', '132'), ('129', '54'), ('116', '7'), ('132', '127'), ('132', '2'), ('132', '28'), ('133', '7'), ('113', '125'), ('113', '23'), ('113', '135'), ('125', '113'), ('135', '113')]
5.分析圖

1 import networkx as nx 2 import matplotlib.pyplot as plt 3 4 G=nx.read_gml("file.gml") 5 UG=G.to_undirected() 6 7 #網絡信息 8 print(nx.info(G)) 9 eccen = nx.eccentricity(UG)#節點離心度 10 print(eccen) 11 print(max(eccen.values())) 12 print(min(eccen.values())) 13 # print(nx.diameter(G)) # 網絡直徑 14 # print(nx.radius(G)) #網絡半徑 15 print(nx.average_shortest_path_length(G)) # 網絡平均最短距離 16 print(nx.average_shortest_path_length(UG)) # 網絡平均最短距離 17 18 #度分布 19 degree=nx.degree_histogram(G)#所有節點的度分布序列 20 print(degree) 21 x=range(len(degree)) #生成x軸序列 22 y=[z/float(sum(degree))for z in degree]#將頻次轉換為頻率 23 plt.loglog(x,y,color='blue',linewidth=2)#在雙對數坐標軸上繪制分布曲線 24 25 #度中心度 26 print(nx.degree_centrality(G))#計算每個點的度中心性 27 print(nx.in_degree_centrality(G))#計算每個點的入度中心性 28 print(nx.out_degree_centrality(G))#計算每個點的出度中心性 29 30 #緊密中心度 31 print(nx.closeness_centrality(G)) 32 33 #介數中心度 34 print(nx.betweenness_centrality(G)) 35 36 #特征向量中心度 37 print(nx.eigenvector_centrality(G)) 38 39 #網絡密度 40 print(nx.density(G)) 41 42 #網絡傳遞性 43 print(nx.transitivity(G)) 44 45 #網絡群聚系數 46 print(nx.average_clustering(UG)) 47 print(nx.clustering(UG)) 48 49 #節點度的匹配性 50 print(nx.degree_assortativity_coefficient(UG)) 51 52 plt.show() 53 ------------------------------------------------------------------
五.補充
1.更精細地畫圖,可以繪制特定的邊和點,一般默認全畫

1 import networkx as nx 2 import matplotlib.pyplot as plt 3 4 #1.獲得帶權圖 5 G = nx.Graph() 6 G.add_edges_from([('a', 'b', {'weight':0.6}), 7 ('a', 'c', {'weight':0.2}), 8 ('a', 'd', {'weight':0.1}), 9 ('c', 'e', {'weight':0.7}) ]) 10 11 #2.對不同權重進行處理,取得相應權重的點集列表,比如weight>0.5的點集列表為[('a', 'b'), ('c', 'e')] 12 elarge = [(u, v) for (u, v, d) in G.edges(data=True) if d['weight'] > 0.5] 13 esmall = [(u, v) for (u, v, d) in G.edges(data=True) if d['weight'] <= 0.5] 14 node1=['a','b'] 15 node2=['c','d','e'] 16 node3={ u:v for (u, v, d) in G.edges(data=True) if d['weight'] > 0.5} 17 edge={(u,v):d['weight'] for (u, v, d) in G.edges(data=True) if d['weight'] > 0.5} 18 19 #3.必須設定一個統一的布局,保證下面分步繪制的圖的統一性,而且分步繪制時pos是一個必須參數 20 pos = nx.spring_layout(G) 21 22 #4.分步繪制完整的圖 23 #(1)繪制點,必須參數(G,pos),還可以指定點集(列表或optional)(默認全點集),形狀,大小,透明度,等 24 nx.draw_networkx_nodes(G,pos=pos,nodelist=node1) 25 nx.draw_networkx_nodes(G,pos=pos,nodelist=node2,node_shape='*',node_color='r',node_size=700) 26 27 #(2)繪制邊,必須參數(G,pos),還可以指定邊集(邊的元組集合(列表))(默認全邊集),形狀,大小,透明度,等 28 nx.draw_networkx_edges(G, pos=pos, edgelist=elarge) 29 nx.draw_networkx_edges(G, pos=pos, edgelist=esmall,edge_color='b',style='dashed', width=3) 30 31 #(3)繪制部分節點的標簽,必須參數(G,pos),還可以指定點集(字典(值)或optional)(默認全點集),形狀,大小,透明度,等 32 #給node3字典中的值‘b’和‘e’添加標簽 33 nx.draw_networkx_labels(G,pos=pos, labels=node3,font_size=18,font_color='b',font_family='sans-serif') 34 35 #(4)繪制邊的標簽,必須參數(G,pos),還可以指定邊集(字典:鍵是邊的元組,值是邊的某個屬性值)(默認全邊集),形狀,大小,透明度,等 36 #根據字典,通過鍵給邊添加值的標簽,{('a', 'b'): 0.6, ('c', 'e'): 0.7} 37 nx.draw_networkx_edge_labels(G,pos=pos,edge_labels=edge,font_size=7,font_color='black',font_family='sans-serif') 38 39 #5.顯示 40 plt.axis('off') 41 plt.show()