文章目录
提醒
- 当用draw_shell(G)画图时,节点命名不能再nlist之外。
- G.adj已经是个元组了,只能
G.adj[1]
要点
- 先掌握建立节点、建立连接、绘制图的方法。
- 调出交互界面需要用到Matplotlib的
plt.show()
- Nodes必须为可哈希对象,我对可哈希的理解是不可以拓展地址范围的对象,如int、float
0.前言
- 学习自:Networkx Analyze in python
- 使用版本:NetworkX2.6 & Python 3.9
- 以下可在Jupyter中执行,这里下载。
1.初始化个图
import matplotlib.pyplot as plt
import networkx as nx
G = nx.Graph()
2.创建Nodes
-
单体建立、群体建立、建立时定义、从别的图合并
-
若因定义多类型节点导致的错误,可以试试
convert_node_labels_to_integers()
-
Q:如何解决有些节点太近导致看不到边的问题?
G.add_node(9)
G.add_nodes_from([
(4, {"color": "red"}),
(5, {"color": "green"}),
])
H = nx.path_graph(5) #Generat a path(a line go through all nodes)
G.add_nodes_from(H)
3.添加边
-
加一边、加多边(同时定性质)、从别的图中加边、有向有权的边。
-
节点不存在时,边也可以加上去,节点会自动补出。
G.add_edge(1, 2,weight=7)
e = (2, 3)
G.add_edge(*e)
G.add_edges_from([(1, 2), (1, 3)])
G.add_edges_from(H.edges)
4.图的信息
- 这些信息包括:节点数、边数、度
- 这些信息是在类中的,直接引用就好
- 把类中的参数当成函数用时,括号里的是想要操作的节点。(见edges()、degree())
- 可以把数据存储到各种container中
list(G.nodes)
[9, 4, 5, 0, 1, 2, 3]
list(G.edges)
[(4, 3), (0, 1), (1, 2), (1, 3), (2, 3)]
list(G.neighbors(1))
[2, 3, 0]
list(G.degree)
[(9, 0), (4, 1), (5, 0), (0, 1), (1, 3), (2, 2), (3, 3)]
G.edges([2, 4])
EdgeDataView([(2, 1), (2, 3), (4, 3)])
5.删除图中信息
- 节点与边双清:
G.clear()
- 与之前的add相关的函数相似
G.remove_node(9)
G.remove_nodes_from([0,3])
6.用已有的实例来画特定的图
- 在这儿找想画的图Link
P = nx.DiGraph(G)
P.add_edges_from([(1, 2), (1, 3),(1, 4)])
7. 访问边与邻居
-
改变边的属性,可以在初始化处、对已有图修改;可以单个、全部
-
由图,权越大表现为距离越短
# P = nx.Graph([(1, 2, {"color": "yellow"})])
P.edges[1, 2]['color'] = "red"
FG = nx.Graph()
FG.add_weighted_edges_from([(1, 2, 4), (1, 3, 0.75), (2, 4, 1.2), (3, 4, 0.375)])
# for n, nbrs in FG.adj.items():
# for nbr, eattr in nbrs.items():
# wt = eattr['weight']
# if wt < 0.5: print(f"({n}, {nbr}, {wt:.3})")
for (u, v, wt) in FG.edges.data('weight'):
if wt < 0.5:
print(f"({u}, {v}, {wt:.3})")
nx.draw(FG, with_labels=True, font_weight='bold')
(3, 4, 0.375)
8.添加属性
-
属性有:权值、颜色、标签等
-
可作用于图、点、边
-
通过键值对添加,开始的时候都是空的
-
需要注意:如果图/点/边尚未存在,不可以直接用修改列表的方式改变(如
G1.nodes[1]['room'] = 663
)。但如果其存在,但这项属性不存在,则可以如此添加。
G1 = nx.Graph(day1="Friday")
G1.graph['day2'] = "Monday"
G1.graph
{'day1': 'Friday', 'day2': 'Monday'}
G1.add_node(1, time='5pm')
G1.nodes[1]['color'] = 'red'
G1.nodes.data()
NodeDataView({1: {'time': '5pm', 'color': 'red'}})
G1.add_edge(1, 2, weight=4.7)
G1.add_edges_from([(3, 4), (4, 5)], color='red')
G1.add_edges_from([(1, 2, {'color': 'blue'}),(2, 3, {'color':'green'})])
G1[1][2]['weight'] = 4.7
G1.edges[3, 4]['weight'] = 4.2
nx.draw(G1, with_labels=True, font_weight='bold')
9. 对有向图的操作
-
可以一开始就将图定为有向图,添加边时先后顺序决定方向
-
有向图中,
neighbors()
变为寻找入度的节点,与successors()
相同 -
需要时可以转为无向图
DG = nx.DiGraph()
DG.add_weighted_edges_from([(1, 2, 0.5), (3, 1, 0.75)])
DG.out_degree(1, weight='weight')
0.5
list(DG.successors(1))
[2]
G2 = nx.Graph(DG) #convert to undirected
G2.edges()
EdgeView([(1, 2), (1, 3)])
10.多边图
- 这种图允许两个节点间有更多权值不同的边连接
MG = nx.MultiGraph()
MG.add_weighted_edges_from([(1, 2, 0.5), (1, 2, 0.75), (2, 3, 0.5)])
dict(MG.degree(weight='weight'))
{1: 1.25, 2: 1.75, 3: 0.5}
11.分析
- 求连通片、所有度值、集群系数等
list(nx.connected_components(G))
[{4}, {5}, {1, 2}]
sorted(d for n, d in G.degree())
[0, 0, 1, 1]
nx.clustering(G)
{4: 0, 5: 0, 1: 0, 2: 0}
12.画出图像
- 图像需要用matlab的交互窗口以及graphviz软件包的接口(后者貌似是用于知晓节点坐标)
- 要画有横纵坐标信息的用
nx.draw_networkx()
- draw的信息不想调也可以用预设的哈
- draw有很多种类型,如sell是同心圆放置
- 对于多图,还有删除、复制等操作,见subplot
plt.subplot(131)
nx.draw(G, with_labels=True, font_weight='bold')
plt.subplot(132)
nx.draw_shell(G,nlist=[range(5,10), range(5)],with_labels=True,font_weight='bold')
plt.subplot(133)
nx.draw(P, with_labels=True, font_weight='bold')
plt.show()