NetworkX的使用

NetworkX是一個多用途的視覺化工具,用於分析、建模和可視化複雜網路拓樸,當然也可應用於各種節點及連線的繪製。它的主要特點和功能如下:

  1. 建構流程圖:我們可以使用NetworkX建立多種類型的圖形,例如有向圖(DiGraph)、無向圖(Graph)等,透過此兩類圖形就能建立各種不同的關係和結構的圖形。
  2. 節點和線:圖形中的各個節點和線(NetworkX稱為edge),可透過相當方便的方式來添加、刪除和檢索,因此,當日後有任何節點變動時,重新構建或修改變得非常方便。
  3. 屬性:每個節點和線就能加入屬性,意思是,可以加入各種重要資訊到圖形的節點或線上。
  4. 分析工具:其了繪製圖形,NetworkX也內建分析工具,包括計算節點度、最短路徑、圖形連通性等,可深入分析並瞭解圖形中各物件的特性和行為。
  5. 演算法:NetworkX提供一些圖形演算法,如最小生成樹、圖形分群、中心性度量等。
  6. 可視化:提供了各種templates及layouts,可視需求來展示圖形的結構和特性,此外,可透過外部的Matplotlib套件來加入更多自定義和圖形外觀更改。
  7. 整合性:NetworkX能夠與其他科學計算庫(如NumPy、SciPy)和可視化庫(如Matplotlib)整合使用,因此亦能應用在數據科學和機器學習中。

A) 節點與線

A.1) 基本範例for 節點及線的繪製

import networkx as nx
import matplotlib.pyplot as plt

# 創建一個無向圖
G = nx.Graph() # DiGraph為有向圖, Graph為無向

# 加入名稱為1, 2, 3的三個節點(字串或數字節可當作節點名稱)
G.add_nodes_from([1, 2, 3])

# 加入節點1 節點2,以及節點2節點3的線
G.add_edges_from([(1, 2), (2, 3)])

# 繪製圖形
nx.draw(G, with_labels=True, font_weight='bold')
plt.show()

程式碼中的創建一個無向圖,範例是使用G = nx.Graph(),你可改為DiGraph()。

執行結果:右側為無向圖nx.Graph(),左側為有向圖DiGraph(),兩者差別在於線條有無箭頭

A.2) 單個節點或線條的屬性修改

上方的範例使用add_nodes_from以及add_edges_from一次加入多個節點及線段.,也可以一次加入單個,並且針對不同節點或線段進行修改。

下方範例使用add_node以及add_edge一個個加入節點及線段,且指定了線條的顏色和寬度。

不過,畫出來的圖形只有一條雙向箭頭的黑線,看來是兩個節點之間的線條重疊在一起了(下圖)。此時,可加入ConnectionStyle參數,讓線段呈現曲線避免重疊。

import networkx as nx
import matplotlib.pyplot as plt

G = nx.DiGraph() #or G = nx.MultiDiGraph()
G.add_node('A')
G.add_node('B')
G.add_edge('A', 'B')
G.add_edge('B', 'A')

nx.draw(G, with_labels=True)

plt.show()

修改下方這行,加入connectionstyle。

nx.draw(G, with_labels=True, connectionstyle='arc3, rad = 0.1')

connectionstyle=’arc3, rad = 0.1′

connectionstyle=’arc3, rad = 0.5′

connectionstyle=’Angle3, angleA=90, angleB=0′

connectionstyle=’Angle3, angleA=30, angleB=0′

A.3) 調整線條的顏色及寬度

將程式修改如下,rad值愈大,則彎曲曲度愈大,其它還有Angle, Bar等方法,可參考https://matplotlib.org/stable/api/_as_gen/matplotlib.patches.ConnectionStyle.html#matplotlib.patches.ConnectionStyle :

G.add_edge('A', 'B',color='r',weight=2)
G.add_edge('B', 'A',color='b',weight=2)

colors = nx.get_edge_attributes(G,'color').values()
weights = nx.get_edge_attributes(G,'weight').values()

nx.draw(G, with_labels=True, edge_color=colors, width=list(weights), connectionstyle='arc3, rad = 0.1')

A.4) 調整節點的大小, 顏色及外形

node_shape, node_color以及node_size, alpha=0.5這四個屬性,可改變節點的外形顏色尺寸,其中alpha的值愈小,代表通透性愈高,因此顏色顯得更淡。

nx.draw(G, with_labels=True,  node_shape="s", node_size=1500, node_color="skyblue", alpha=0.4, edge_color=colors, width=list(weights), connectionstyle='arc3, rad = 0.1')

A.5) 下方是一個較複雜的例子

import networkx as nx
import matplotlib.pyplot as plt

# 創建一個有向圖
G = nx.DiGraph()

# 添加帶有屬性的節點
G.add_node(1, label="A")
G.add_node(2, label="B")
G.add_node(3, label="C")
G.add_node(4, label="D")

# 添加帶有權重的有向邊
G.add_edge(1, 2, weight=0.5)
G.add_edge(1, 3, weight=0.9)
G.add_edge(2, 3, weight=0.2)
G.add_edge(3, 4, weight=1.5)

# 計算節點的入度和出度
in_degrees = dict(G.in_degree())
out_degrees = dict(G.out_degree())

# 計算最短路徑
shortest_path = nx.shortest_path(G, source=1, target=4)

# 可視化圖形
pos = nx.spring_layout(G) # 使用Spring布局算法排列節點
labels = nx.get_edge_attributes(G, 'weight')
nx.draw(G, pos, with_labels=True, node_size=700, node_color="skyblue", font_size=10, font_color="black")
nx.draw_networkx_edge_labels(G, pos, edge_labels=labels)

# 顯示最短路徑
plt.text(0.5, -0.5, f'Shortest Path:\n {shortest_path}', horizontalalignment='center', verticalalignment='center')

# 顯示節點的入度和出度
for node, in_degree in in_degrees.items():
plt.text(pos[node][0], pos[node][1] + 0.1, f'In: {in_degree}', horizontalalignment='center', verticalalignment='center')
for node, out_degree in out_degrees.items():
plt.text(pos[node][0], pos[node][1] - 0.1, f'Out: {out_degree}', horizontalalignment='center', verticalalignment='center')

plt.show()

繪出的圖颪如下:

上方這程式會計算每一個節點的入度和出度,這是什麼呢?

在有向圖中,每個節點都有一個相應的入度值和出度值。此兩個值可透過G.in_degree()和G.out_degree()函數取得。

入度(In-Degree): 指的是一個節點被指向的數量。換句話說,入度表示有多少條線指向該節點。

出度(Out-Degree): 指的是一個節點指向別人的數量。換句話說,出度表示有多少條線從該節點指向其他節點。

入度值和出度值在分析有向圖的結構和流動性時非常有用。例如,入度可以用來衡量一個網路節點的「受歡迎程度」,因為入度越高,表示越多的其他節點與該節點有直接的指向關係。出度則反映了該節點對其他節點的直接影響程度。

B) 應用於大量的RD工作站

目前RD工作站環境有持續搜集各工作站到ITNA5、SVM04 storage的過去五分鐘傳輸量,因此,我們把這些資訊讀入後利用NetworkX來繪製圖表,讓目前RD工作站的狀況可用圖像化方式實時的顯示。程式的運作邏輯如下:

  1. 由於各工作站會自動休眠,因此先用ping指令,搜集目前有開機運作的工作站。
  2. 取得了開機中的工作站列表,依次查詢取得各工作站的資訊:最近五分鐘,與ITNA5、SVM04傳輸的資料量。(該資料可從RD Monitor系統中取得)
  3. 依據不同的傳輸量,可改變線條的顏色及寬度,讓可視化的程度愈高。
  4. 如上圖,TX及RX分別代表工作站到storage,以及storage到工作站的五分鐘傳輸量。
C:\Users\ch.tseng\AppData\Local\Packages\Microsoft.Windows.Photos_8wekyb3d8bbwe\TempState\ShareServiceTempFolder\output.jpeg