生物医学网络科学Biomedical Network Science
Example08 / 09

布局算法比较与布局质量的定量检查

所属专题
网络分析流程与 NetworkX 实践
下载
Notebook · .py

在一个有 4 个植入模块的随机分块网络(SBM)上比较五种布局:spring(Fruchterman–Reingold)、 Kamada–Kawai、谱布局、ForceAtlas2 与按模块分层的 multipartite 布局。 用“图距离与欧氏距离的 Spearman 相关”衡量布局对网络距离的保真程度,并计算同模块节点对与异模块节点对 的平均欧氏距离之比(越小说明模块在图上越分得开)。输出各布局的两项指标与一张 5 联图。 解读:不同布局优化不同目标,看起来“分得开”的模块可能部分是布局算法造成的,不应仅凭网络图下结论。

Output输出图

布局算法比较与布局质量的定量检查:输出图 1

Output文字输出

spring        图距离–欧氏距离 ρ = 0.63,同模块/异模块平均距离比 = 0.39
kamada_kawai  图距离–欧氏距离 ρ = 0.76,同模块/异模块平均距离比 = 0.42
spectral      图距离–欧氏距离 ρ = 0.68,同模块/异模块平均距离比 = 0.17
forceatlas2   图距离–欧氏距离 ρ = 0.71,同模块/异模块平均距离比 = 0.25
multipartite  图距离–欧氏距离 ρ = 0.03,同模块/异模块平均距离比 = 1.00

Code代码

# 在一个有 4 个植入模块的随机分块网络(SBM)上比较五种布局:spring(Fruchterman–Reingold)、
# Kamada–Kawai、谱布局、ForceAtlas2 与按模块分层的 multipartite 布局。
# 用“图距离与欧氏距离的 Spearman 相关”衡量布局对网络距离的保真程度,并计算同模块节点对与异模块节点对
# 的平均欧氏距离之比(越小说明模块在图上越分得开)。输出各布局的两项指标与一张 5 联图。
# 解读:不同布局优化不同目标,看起来“分得开”的模块可能部分是布局算法造成的,不应仅凭网络图下结论。
import numpy as np
import networkx as nx
import matplotlib
import matplotlib.pyplot as plt
from scipy.stats import spearmanr

sizes = [25, 25, 25, 25]
P = np.full((4, 4), 0.01) + np.eye(4) * 0.24
G = nx.stochastic_block_model(sizes, P.tolist(), seed=7)
G = G.subgraph(max(nx.connected_components(G), key=len)).copy()
block = {v: G.nodes[v]["block"] for v in G}
nx.set_node_attributes(G, block, "layer")

layouts = {
    "spring": nx.spring_layout(G, seed=1),
    "kamada_kawai": nx.kamada_kawai_layout(G),
    "spectral": nx.spectral_layout(G),
    "forceatlas2": nx.forceatlas2_layout(G, seed=1, max_iter=300),
    "multipartite": nx.multipartite_layout(G, subset_key="layer"),
}
nodes = list(G)
spl = dict(nx.all_pairs_shortest_path_length(G))
iu = np.triu_indices(len(nodes), 1)
gd = np.array([[spl[u][v] for v in nodes] for u in nodes])[iu]
same = np.array([[block[u] == block[v] for v in nodes] for u in nodes])[iu]

fig, axes = plt.subplots(1, 5, figsize=(16, 3.4))
for ax, (name, pos) in zip(axes, layouts.items()):
    X = np.array([pos[v] for v in nodes])
    ed = np.sqrt(((X[:, None, :] - X[None, :, :]) ** 2).sum(-1))[iu]
    rho = spearmanr(gd, ed).correlation
    ratio = ed[same].mean() / ed[~same].mean()
    print("%-13s 图距离–欧氏距离 ρ = %.2f,同模块/异模块平均距离比 = %.2f" % (name, rho, ratio))
    nx.draw_networkx(G, pos, ax=ax, node_size=25, with_labels=False, width=0.3,
                     node_color=[block[v] for v in nodes], cmap="tab10", vmin=0, vmax=9)
    ax.set_title("%s (rho=%.2f)" % (name, rho), fontsize=9); ax.axis("off")
plt.tight_layout(); plt.show()

Run在浏览器中运行

首次加载 Python 环境约需 20–40 秒;可以修改参数后重新运行。

布局算法比较与布局质量的定量检查