K_DM Book
用語集
対象者 標準
対象者別の入口 →

対象者の設定はこのブラウザの中にだけ保存されます。

言語 JA

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

中級

06.7.30

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

最終更新 2026-03-06 読了時間 3 分
まとめ
ネットワークグラフは、人や物を点(ノード)、関係を線(エッジ)で表し、つながりの強い者どうしが近くに集まるように配置した図です。Force-directed(力学)レイアウトは、エッジをバネ、ノードどうしを反発する電荷に見立ててシミュレーションし、密につながった集団が自然に塊(コミュニティ)として現れます。networkx では nx.spring_layout(G, seed=42) が座標を計算し、draw_networkx_nodes / edges / labels の 3 関数で描画します。読み終えると、部署内で 70% の確率でつながり部署間は 5 本だけの橋でつながる 15 人のグラフから、次数の大きいハブと部署をまたぐブリッジを読み取り、自分の関係データで同じ図を描けるようになります。

直感 #

開発・営業・企画の 3 部署 15 人について「誰と誰がよく話すか」を調べたとします。隣接行列の 15 × 15 の表を眺めても、部署間の橋渡しをしている人は見つけにくいものです。力学レイアウトは、話す相手どうしをバネで引き寄せ、全員を電荷として反発させた状態で釣り合いの位置を求めます。結果として同じ部署の 5 人は密な塊になり、別の部署とつながる人はその塊の端に引っ張られて位置します。ノードの大きさを「つながりの本数(次数)」にすれば中心人物が、エッジの太さを「会話の頻度(重み)」にすれば強い結びつきが、それぞれ目で分かります。

Python で描く #

次のコードは、3 部署 × 5 人のノードを作り、同じ部署内は 70% の確率で重み 1〜3 のエッジ、部署をまたぐ 5 組だけ重み 0.3〜1.0 の弱いエッジでつなぎます。spring_layout で座標を求め、次数に応じたノードサイズと重みに応じたエッジ幅で描きます。

 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()

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

実行結果の読み方 #

同じ色のノードが 3 つの塊を作り、それぞれが 1 つの部署です。塊の中で大きく描かれたノードは次数が多い「ハブ」で、その人を介して部署内の情報が回っていると読めます。塊どうしをつなぐ細い線がブリッジで、この例では田中–渡辺、鈴木–吉田など 5 本だけなので、部署間の情報共有はこの 5 人に依存していると分かります。ブリッジの両端のノードが塊の端に引っ張られて配置されるのは、力学レイアウトが別の塊からも引力を受けるためです。

使いどころと落とし穴 #

ネットワークグラフは、ノードが 10〜100 程度の共著関係、共起関係、依存関係のグラフでコミュニティとハブを探索するときに向いています。ノードが 500 を超えると spring_layout の計算が遅くなり、エッジが絡まった「毛玉」になって何も読めないので、weight に閾値を設けてエッジを間引くか、コミュニティごとに分けて描くか、Gephi や Cytoscape のような専用ツールに移します。seed を固定しないと同じデータでも実行ごとに配置が変わるため、レポートに載せる図では必ず指定してください。階層構造(上司と部下、親カテゴリと子カテゴリ)が本質のデータなら、力学配置よりデンドログラムやサンバーストの方が構造を正確に伝えます。