乃木撮を使ってnetworkXについて勉強する。Vol.03

# はじめに
前回は「[乃木撮を使ってnetworkXについて勉強する。Vol.02](https://qiita.com/Hakoshi/items/422d935a99816f0efbd5
 "Qiita Home")」
という記事で、写真集から作成したリストデータを使ってグラフを描画してみました。

```python:
photos_01 = [
    ('新内眞衣', '齋藤飛鳥'),  # 01-001
    ('若月佑美', '白石麻衣', '衛藤美彩'),  # 01-002
    ('斉藤優里', '西野七瀬'),  # 01-003
    ('堀未央奈', '衛藤美彩', '秋元真夏'),  # 01-004
    ('秋元真夏', '生田絵梨花'),  # 01-005
    ('秋元真夏', '白石麻衣'),  # 01-006
    ('伊藤万理華', '星野みなみ', '西野七瀬', '若月佑美', '松村沙友理'),  # 01-007
    ('伊藤万理華', '松村沙友理'),  # 01-008
    ('斉藤優里', '生田絵梨花'),  # 01-009
    ('伊藤万理華', '西野七瀬', '衛藤美彩', '高山一実', '秋元真夏'),  # 01-010
         .
         .
         .
     （中略）
    ]
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3999109/0d07e53c-4347-40d4-a938-0241b3415685.png)


# spring_layout以外のレイアウトについて
NetworkXにはspring_layout以外にもいくつかのレイアウトがあります。たいていの場合はspring_layoutで足りるようですが、他のレイアウトを使った場合にどうなるのかやってみました。

### circular_layout
ノードを円形に配置します。
効果的な場面: グラフのすべてのノードを均等に強調表示したいとき。
特徴: ノードが円形に配置されるため、対称性があり見やすい。
使用例: ソーシャルネットワークの小規模なグラフ、コミュニティの可視化。

```python:
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()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3999109/adabc634-8fb2-4a60-965f-d549a93ee27f.png)
たしかにエッジの太さについては見やすいように思われます。

### random_layout
ノードをランダムに配置します。
効果的な場面: ノードの初期配置を無作為に行いたいとき。
特徴: ノードがランダムに配置されるため、特に特徴がないが、初期状態として利用されることが多い。
使用例: レイアウトアルゴリズムの比較、初期配置の設定。
```python
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()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3999109/3ecd4db7-8605-4db0-8d9e-8e37790786c5.png)
なんだかよくわからない図になりました。

### shell_layout
与えられたノードリストに基づいて、ノードを同心円状に配置します。
効果的な場面:階層的な構造を持つグラフを表現したいとき。
特徴：ノードを同心円状に配置することで、グラフの構造を視覚的に分かりやすく表現できます。ノードリストを指定することで、各ノードをどの円に配置するかを細かく制御できます。
使用例：ソーシャルネットワークの可視化、組織図の可視化、生物学的なネットワークの可視化など。

```python
# ノードリストを作成
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()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3999109/10359cab-d2af-4373-b8d2-e7d16fc20b33.png)

```python
# 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()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3999109/dcd3c32a-ea2c-445b-ba62-64ffd36cba2a.png)

ノードについては対称性のあるきれいな図が作成できましたし、ノードの位置も自分で調整しやすいのですが、関係性は分かりにくいです。使う場面を選べば効果的だと思います。


### spectral_layout
グラフの隣接行列の固有ベクトルを使用してノードを配置します。
効果的な場面: グラフのクラスタリングやコミュニティ構造を可視化するとき。
特徴: 関連性の高いノードは近くに配置されます。
使用例: 高度なグラフ分析、数学的性質を強調したい場合。

```python
# 辺の重み情報から隣接行列（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()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3999109/ad4aa544-b0c4-412f-8a55-5f028b42a0aa.png)
なんか良さそうだけど、よくわからないというのが正直なところ。
関連性の高いノードが近くに配置されているとは言い難いのでは？

### kamada_kawai_layout
Kamada-Kawai力指向アルゴリズムに基づいてノードを配置します。
効果的な場面: ノード間の距離をできるだけ均一に配置したいとき。
特徴: Kamada-Kawai力指向アルゴリズムによる配置で、ノード間のエネルギーを最小化する。
使用例: 力指向グラフ、ネットワークの均一な可視化。

```python
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()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3999109/231eafac-40c3-4384-b597-5bd2d7479591.png)
よいのか悪いのか、よくわからないです。

### spiral_layout
効果的な場面: ノードを螺旋状に配置したいとき。
特徴: ノードが螺旋状に配置されるため、特定の順序を持つデータの視覚化に役立つ。

```python
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()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3999109/9e864b96-f747-440d-9975-5c60c8239cb0.png)
今回は五十音順にノードを並べており、このレイアウトにふさわしい場面ではないようです。

### multipartite_layout
効果的な場面: 多部構造のグラフを視覚化したいとき。
特徴: ノードを複数のパートに分けて配置し、各パート間の関係を強調する。

```python
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()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3999109/5da8170d-37f0-46e9-8c65-72983aa2f155.png)
期別でパート分けされた乃木坂46メンバーのネットワークが描画されましたが、グラフが複雑なため、視覚的に分かりやすいとはいえません。

# まとめ
色々なレイアウトがありましたが、結局spring_layoutを使うのが一番楽できれいでよいことがわかりました。