Tutorialに学ぶNetworkXの使い方③|Pythonによる可視化入門 #15

f:id:lib-arts:20191228172252p:plain

#1〜#4まではMatplotlibに関して、#5〜#8まではseabornについて、#9〜#12ではPillowについてまとめました。

Matplotlibの使い方①(plt.plot、plt.scatter、plt.hist)|Pythonによる可視化入門 #1 - lib-arts’s diary

Tutorialに学ぶseabornの使い方①(概要&Visualizing statistical relationships)|Pythonによる可視化入門 #5 - lib-arts’s diary

Tutorialに学ぶPillowの使い方①(Visualizing linear relationships)|Pythonによる可視化入門 #9 - lib-arts’s diary
#13からはPython環境でグラフ(グラフ理論のグラフで、ノードとエッジから構成されます)を描画するツールである、NetworkXについて取り扱います。

Tutorial — NetworkX 2.4 documentation

#14ではチュートリアルより、"Creating a graph""、"Nodes"、"Edges"について取り扱いました。

Tutorialに学ぶNetworkXの使い方②|Pythonによる可視化入門 #14 - lib-arts’s diary

#15ではチュートリアルより、"Accessing edges and neighbors"、"Adding attributes to graphs, nodes, and edges"について取り扱います。
以下、目次になります。
1. Accessing edges and neighborsについて
2. Adding attributes to graphs, nodes, and edgesについて
3. まとめ


1. Accessing edges and neighborsについて
1節では"Accessing edges and neighbors"の内容について取り扱います。

f:id:lib-arts:20200106183711p:plain

Tutorial — NetworkX 2.4 documentation

冒頭部では、「Graph.edges()やGraph.adj()に加えて、サブスクリプトのnotationを用いることでエッジや隣接するノードにアクセスすることが可能である」と記載されています。以下具体的に実装を元に確認していきます。まずは#14同様に下記を動作させます。

import networkx as nx
import matplotlib.pyplot as plt

G = nx.Graph()
H = nx.path_graph(10)
G.add_nodes_from(H)
G.add_edges_from([(0, 1), (1, 2)])
nx.draw(G, with_labels=True)

plt.show(G)

上記の動作結果は下記になります。

f:id:lib-arts:20200106185549p:plain

次に下記を動作させます。

print(G[1])
print(G.adj[1])

print(G[1][2])
print(G.edges[1, 2])

動作結果は下記のようになります。

f:id:lib-arts:20200106185702p:plain

G[1]やG.adj[1]はノード1と隣接するノードを出力しています。また、G[1][2]やG.edges[1,2]は1と2が隣接していなければエラーを返すようになっています。{}に何も入っていないのはエッジに属性を持たせていないためです。エッジに属性を持たせた重み付きのグラフで確認してみます。

FG = nx.Graph()
FG.add_weighted_edges_from([(1, 2, 0.125), (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('(%d, %d, %.3f)' % (n, nbr, wt))

print("====")
print(FG[2])
print(FG[1][3])

nx.draw(FG, with_labels=True)
plt.show(FG)

上記の実行結果は下記のようになります。

f:id:lib-arts:20200106190231p:plain

それぞれのエッジに重みを付加しています。そのため、最初の例では{}内に何も入っていなかったですが、値を持つようになっています。

大体の要旨について確認できたので1節はここまでとします。


2. Adding attributes to graphs, nodes, and edgesについて
2節では"Adding attributes to graphs, nodes, and edges"の内容について取り扱います。

f:id:lib-arts:20200106190522p:plain

Tutorial — NetworkX 2.4 documentation
冒頭部では、「重みやラベル、色といった任意のPythonオブジェクトをグラフやノード、エッジに付加することができる」と記載されています。情報の付加にあたってはそれぞれ、Graph attributes、Node attributes、Edge Attributesに分けて記述されています。以下具体的に実装を元に確認していきます。

G = nx.Graph(day="Friday")
print(G.graph)

G.graph['day'] = "Monday"
print(G.graph)

まずはGraph attributesについて確認します。上記の実行結果は下記のようになります。

f:id:lib-arts:20200106191200p:plain

グラフにdayという属性を追加し、初期値として"Friday"を与えた後、"Monday"に書き換えています。
次にNode attributesについて確認します。

G = nx.Graph()
G.add_node(1, time='5pm')
G.add_nodes_from([3], time='2pm')
print(G.nodes[1])

G.nodes[1]['room'] = 714
print(G.nodes.data())

上記の実行結果は下記のようになります。

f:id:lib-arts:20200106191654p:plain

ノードに様々な属性を付与したり、G.nodes.data()で情報を引き出したりしています。
次にEdge attributesについて確認します。

G = nx.Graph()
G.add_edge(1, 2, weight=4.7 )
G.add_edges_from([(3, 4), (4, 5)], color='red')
G.add_edges_from([(1, 2, {'color': 'blue'}), (2, 3, {'weight': 8})])
G[1][2]['weight'] = 4.7
G.edges[3, 4]['weight'] = 4.2

print(G[4])
print(G[2])

nx.draw(G, with_labels=True)
plt.show(G)

上記の実行結果は下記のようになります。

f:id:lib-arts:20200106192130p:plain

上記のようにエッジに属性を与え、1節で取り扱った隣接ノードとのエッジを出力する機能を用いて属性について確認しています。

大体の内容について把握できたので2節はここまでとします。


3. まとめ
#15ではチュートリアルより、"Accessing edges and neighbors"、"Adding attributes to graphs, nodes, and edges"について取り扱いました。
#16では"Directed graphs"以降の内容について取り扱います。