はじめに
前回は「乃木撮を使ってnetworkXについて勉強する。Vol.02」
という記事で、写真集から作成したリストデータを使ってグラフを描画してみました。
photos_01 = [
('新内眞衣', '齋藤飛鳥'), # 01-001
('若月佑美', '白石麻衣', '衛藤美彩'), # 01-002
('斉藤優里', '西野七瀬'), # 01-003
('堀未央奈', '衛藤美彩', '秋元真夏'), # 01-004
('秋元真夏', '生田絵梨花'), # 01-005
('秋元真夏', '白石麻衣'), # 01-006
('伊藤万理華', '星野みなみ', '西野七瀬', '若月佑美', '松村沙友理'), # 01-007
('伊藤万理華', '松村沙友理'), # 01-008
('斉藤優里', '生田絵梨花'), # 01-009
('伊藤万理華', '西野七瀬', '衛藤美彩', '高山一実', '秋元真夏'), # 01-010
.
.
.
(中略)
]
spring_layout以外のレイアウトについて
NetworkXにはspring_layout以外にもいくつかのレイアウトがあります。たいていの場合はspring_layoutで足りるようですが、他のレイアウトを使った場合にどうなるのかやってみました。
circular_layout
ノードを円形に配置します。
効果的な場面: グラフのすべてのノードを均等に強調表示したいとき。
特徴: ノードが円形に配置されるため、対称性があり見やすい。
使用例: ソーシャルネットワークの小規模なグラフ、コミュニティの可視化。
plt.figure(figsize=(30, 30))
nx.draw_networkx(G,
pos=nx.circular_layout(G),
node_color=node_color,
alpha=0.5,
node_size=node_size,
with_labels=True,
font_family="IPAexGothic",
font_size=20,
width=edge_weight,
edge_color='black'
)
plt.show()
random_layout
ノードをランダムに配置します。
効果的な場面: ノードの初期配置を無作為に行いたいとき。
特徴: ノードがランダムに配置されるため、特に特徴がないが、初期状態として利用されることが多い。
使用例: レイアウトアルゴリズムの比較、初期配置の設定。
plt.figure(figsize=(30, 30))
nx.draw_networkx(G,
pos=nx.random_layout(G),
node_color=node_color,
alpha=0.5,
node_size=node_size,
with_labels=True,
font_family="IPAexGothic",
font_size=20,
width=edge_weight,
edge_color='black')
plt.show()
shell_layout
与えられたノードリストに基づいて、ノードを同心円状に配置します。
効果的な場面:階層的な構造を持つグラフを表現したいとき。
特徴:ノードを同心円状に配置することで、グラフの構造を視覚的に分かりやすく表現できます。ノードリストを指定することで、各ノードをどの円に配置するかを細かく制御できます。
使用例:ソーシャルネットワークの可視化、組織図の可視化、生物学的なネットワークの可視化など。
# ノードリストを作成
shell_1 = [person for person in G.nodes if G.nodes[person]['generation'] == 1]
shell_2 = [person for person in G.nodes if G.nodes[person]['generation'] == 2]
shell_3 = [person for person in G.nodes if G.nodes[person]['generation'] == 3]
shells = [shell_1, shell_2, shell_3]
plt.figure(figsize=(15, 15))
nx.draw_networkx(G,
pos = nx.shell_layout(G, shells),
node_color=node_color,
alpha=0.5,
node_size=node_size,
with_labels=True,
font_family="IPAexGothic",
font_size=15,
width=edge_weight,
edge_color='black')
plt.show()
# shellの順番を変える
shells = [shell_3, shell_2, shell_1]
plt.figure(figsize=(15, 15))
nx.draw_networkx(G,
pos = nx.shell_layout(G, shells),
node_color=node_color,
alpha=0.5,
node_size=node_size,
with_labels=True,
font_family="IPAexGothic",
font_size=15,
width=edge_weight,
edge_color='black')
plt.show()
ノードについては対称性のあるきれいな図が作成できましたし、ノードの位置も自分で調整しやすいのですが、関係性は分かりにくいです。使う場面を選べば効果的だと思います。
spectral_layout
グラフの隣接行列の固有ベクトルを使用してノードを配置します。
効果的な場面: グラフのクラスタリングやコミュニティ構造を可視化するとき。
特徴: 関連性の高いノードは近くに配置されます。
使用例: 高度なグラフ分析、数学的性質を強調したい場合。
# 辺の重み情報から隣接行列(adj_matrix)を作成する
adj_matrix = nx.adjacency_matrix(G, weight='weight')
# 固有値と固有ベクトルの計算
eigenvalues, eigenvectors = np.linalg.eig(adj_matrix.toarray())
pos = {node: (eigenvectors[node_idx, 1], eigenvectors[node_idx, 2]) for node_idx, node in enumerate(G.nodes())}
plt.figure(figsize=(30, 30))
nx.draw_networkx(G,
pos,
node_color=node_color,
alpha=0.5,
node_size=node_size,
with_labels=True,
font_family="IPAexGothic",
font_size=20,
width=edge_weight,
edge_color='black')
plt.show()
なんか良さそうだけど、よくわからないというのが正直なところ。
関連性の高いノードが近くに配置されているとは言い難いのでは?
kamada_kawai_layout
Kamada-Kawai力指向アルゴリズムに基づいてノードを配置します。
効果的な場面: ノード間の距離をできるだけ均一に配置したいとき。
特徴: Kamada-Kawai力指向アルゴリズムによる配置で、ノード間のエネルギーを最小化する。
使用例: 力指向グラフ、ネットワークの均一な可視化。
plt.figure(figsize=(30, 30))
nx.draw_networkx(G,
pos = nx.kamada_kawai_layout(G),
node_color=node_color,
alpha=0.5,
node_size=node_size,
with_labels=True,
font_family="IPAexGothic",
font_size=20,
width=edge_weight,
edge_color='black')
plt.show()
spiral_layout
効果的な場面: ノードを螺旋状に配置したいとき。
特徴: ノードが螺旋状に配置されるため、特定の順序を持つデータの視覚化に役立つ。
plt.figure(figsize=(30, 30))
nx.draw_networkx(G,
pos = nx.spiral_layout(G),
node_color=node_color,
alpha=0.5,
node_size=node_size,
with_labels=True,
font_family="IPAexGothic",
font_size=20,
width=edge_weight,
edge_color='black')
plt.show()
今回は五十音順にノードを並べており、このレイアウトにふさわしい場面ではないようです。
multipartite_layout
効果的な場面: 多部構造のグラフを視覚化したいとき。
特徴: ノードを複数のパートに分けて配置し、各パート間の関係を強調する。
plt.figure(figsize=(30, 30))
nx.draw_networkx(G,
pos = nx.multipartite_layout(G, subset_key='generation'),
node_color=node_color,
alpha=0.5,
node_size=node_size,
with_labels=True,
font_family="IPAexGothic",
font_size=20,
width=edge_weight,
edge_color='black')
plt.show()
期別でパート分けされた乃木坂46メンバーのネットワークが描画されましたが、グラフが複雑なため、視覚的に分かりやすいとはいえません。
まとめ
色々なレイアウトがありましたが、結局spring_layoutを使うのが一番楽できれいでよいことがわかりました。