ネットワークグラフで関係性を力学レイアウトで描く

中級

6.7.30

ネットワークグラフで関係性を力学レイアウトで描く

最終更新 2026-03-06 読了時間 2 分
まとめ
  • ノードとエッジで構成されるグラフデータを力学モデルで配置し、コミュニティや中心性を可視化する。
  • networkx + matplotlib で Force-directed レイアウトを数行で描画できる。
  • ソーシャルネットワーク分析、共起関係、ナレッジグラフなど関係性データの探索に使う。

ネットワークグラフ(Force-directed Graph)はノード間の接続をバネ模型でシミュレーションし、関連の強いノードを近くに、弱いノードを遠くに配置する。コミュニティ構造が自然にクラスターとして現れる。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import numpy as np
import matplotlib.pyplot as plt
import networkx as nx

rng = np.random.default_rng(42)

G = nx.Graph()

# 3つのコミュニティを作成
communities = {
    "開発": ["田中", "鈴木", "佐藤", "高橋", "伊藤"],
    "営業": ["渡辺", "山本", "中村", "小林", "加藤"],
    "企画": ["吉田", "山田", "松本", "井上", "木村"],
}
colors_map = {"開発": "#2563eb", "営業": "#10b981", "企画": "#ef4444"}

node_colors = []
for dept, members in communities.items():
    G.add_nodes_from(members)
    node_colors.extend([colors_map[dept]] * len(members))
    # コミュニティ内は密に接続
    for i, a in enumerate(members):
        for b in members[i + 1 :]:
            if rng.random() < 0.7:
                G.add_edge(a, b, weight=rng.uniform(1, 3))

# コミュニティ間は疎に接続
cross_edges = [
    ("田中", "渡辺"), ("鈴木", "吉田"), ("高橋", "山本"),
    ("伊藤", "松本"), ("中村", "山田"),
]
for a, b in cross_edges:
    G.add_edge(a, b, weight=rng.uniform(0.3, 1.0))

pos = nx.spring_layout(G, seed=42, k=1.5)
degrees = dict(G.degree())
node_sizes = [300 + degrees[n] * 120 for n in G.nodes()]
edge_weights = [G[u][v]["weight"] for u, v in G.edges()]

fig, ax = plt.subplots(figsize=(9, 7))
nx.draw_networkx_edges(G, pos, ax=ax, alpha=0.3, width=edge_weights)
nx.draw_networkx_nodes(
    G, pos, ax=ax, node_color=node_colors,
    node_size=node_sizes, edgecolors="white", linewidths=1.5,
)
nx.draw_networkx_labels(G, pos, ax=ax, font_size=9, font_family="sans-serif")

# 凡例
for dept, color in colors_map.items():
    ax.scatter([], [], c=color, s=100, label=dept)
ax.legend(loc="upper left", title="部署")
ax.set_title("部署間コミュニケーション ネットワーク")
ax.axis("off")

fig.tight_layout()
plt.show()

部署間コミュニケーションのネットワークグラフ

読み方のポイント #

  • ノードの大きさが次数(接続数)を表す。大きいノードほど多くの人とつながっている「ハブ」。
  • 同じ色のノードが近くに集まっているほど、そのコミュニティ内の結束が強い。
  • コミュニティ間をつなぐエッジ(ブリッジ)が少ない場合、部門間の情報共有が弱いことを示唆する。

いつ使うか #

  • 適している場面: ノード数 10〜100 程度のグラフで、コミュニティ構造やハブを探索したいとき。共著ネットワーク、共起分析、依存関係グラフなど。
  • 不向きな場面: ノード数が 500 を超えると描画が遅く、エッジが絡まって判読困難になる。
  • 代替手段: 大規模グラフには Gephi や Cytoscape などの専用ツール。階層構造にはデンドログラムやサンバーストチャートが適切。

よくある失敗パターン #

  • エッジの「ヘアボール」問題: ノード数やエッジ数が多すぎると毛玉状になって何も読めない。エッジの閾値フィルタリングやコミュニティごとの分離描画で対処する。
  • レイアウトの不安定さ: spring_layout はランダムシードで結果が変わる。seed パラメーターを固定して再現性を確保する。