python-igraph 手册

用于从 Python 使用 igraph

生成聚类图

生成聚类图

此示例展示了如何在一个图中找到社群,然后使用 cluster_graph() 将每个社群收缩为一个单独的节点。在本教程中,我们将使用唐纳德·克努特的悲惨世界网络,该网络展示了小说悲惨世界中人物的共同出现情况。该网络可以从此处获得。

import igraph as ig
import matplotlib.pyplot as plt

# Load the graph
g = ig.load("./lesmis/lesmis.gml")

首先,让我们可视化原始社群,使用 community_edge_betweenness() 将顶点分离成不同的簇。(对于更专注于可视化社群的教程,请查看社群)。

# Generate communities
communities = g.community_edge_betweenness()
communities = communities.as_clustering() # Convert into a VertexClustering for plotting

# Print them out
for i, community in enumerate(communities):
    print(f"Community {i}:")
    for v in community:
        print(f"\t{g.vs[v]['label']}")

# Set community colors
num_communities = len(communities)
palette1 = ig.RainbowPalette(n=num_communities)
for i, community in enumerate(communities):
    g.vs[community]["color"] = i
    community_edges = g.es.select(_within=community)
    community_edges["color"] = i

g.vs["label"] = ["\n\n" + label for label in g.vs["label"]] # Move the labels below the vertices

# Plot the communities
fig1, ax1 = plt.subplots()
ig.plot(
    communities,
    target=ax1,
    mark_groups=True,
    palette=palette1,
    vertex_size=0.1,
    edge_width=0.5,
)
fig1.set_size_inches(20, 20)
fig1.savefig("../figures/communities.png", dpi=200)

现在让我们尝试收缩信息,仅使用单个顶点来表示每个社群。我们首先为原始图中的每个节点定义属性值。

# Assign x, y, and sizes for each node
layout = g.layout_kamada_kawai()
g.vs["x"], g.vs["y"] = list(zip(*layout))
g.vs["size"] = 1
g.es["size"] = 1

这样我们就可以定义当我们调用 cluster_graph() 时,如何将这些属性组合在一起。

# Generate cluster graph
cluster_graph = communities.cluster_graph(
    combine_vertices={
        "x": "mean",
        "y": "mean",
        "color": "first",
        "size": "sum",
    },
    combine_edges={
        "size": "sum",
    },
)

在这里,我们取 x 和 y 值的平均值,以便聚类图中的节点位于原始聚类位置的中心。

注意

meanfirstsum 都是内置的折叠函数,以及 prodmedianmaxminlastrandom。您还可以定义自己的自定义折叠函数,该函数接收一个列表并返回一个表示组合属性值的单个元素。有关igraph收缩的更多详细信息,请参阅contract_vertices()

最后,我们使用计算出的属性绘制图

# Plot the cluster graph
palette2 = ig.GradientPalette("gainsboro", "black")
g.es["color"] = [palette2.get(int(i)) for i in ig.rescale(cluster_graph.es["size"], (0, 255), clamp=True)]

fig2, ax2 = plt.subplots()
ig.plot(
    cluster_graph,
    target=ax2,
    palette=palette1,
    # set a minimum size on vertex_size, otherwise vertices are too small
    vertex_size=[max(0.2, size / 20) for size in cluster_graph.vs["size"]],
    edge_color=g.es["color"],
    edge_width=0.8,
)

# Add a legend
legend_handles = []
for i in range(num_communities):
    handle = ax2.scatter(
        [], [],
        s=100,
        facecolor=palette1.get(i),
        edgecolor="k",
        label=i,
    )
    legend_handles.append(handle)

ax2.legend(
    handles=legend_handles,
    title='Community:',
    bbox_to_anchor=(0, 1.0),
    bbox_transform=ax2.transAxes,
)

fig2.set_size_inches(10, 10)
fig2.savefig("../figures/cluster_graph.png", dpi=150)

这里并排显示了两个图

pic1 pic2

……我们打印出的社群的最终输出显示在下方

Community 0:
    Myriel
    Napoleon
    MlleBaptistine
    MmeMagloire
    CountessDeLo
    Geborand
    Champtercier
    Cravatte
    Count
    OldMan
Community 1:
    Labarre
    Valjean
    MmeDeR
    Isabeau
    Gervais
    Bamatabois
    Simplice
    Scaufflaire
    Woman1
    Judge
    Champmathieu
    Brevet
    Chenildieu
    Cochepaille
Community 2:
    Marguerite
    Tholomyes
    Listolier
    Fameuil
    Blacheville
    Favourite
    Dahlia
    Zephine
    Fantine
    Perpetue
Community 3:
    MmeThenardier
    Thenardier
    Javert
    Pontmercy
    Eponine
    Anzelma
    Gueulemer
    Babet
    Claquesous
    Montparnasse
    Brujon
Community 4:
    Cosette
    Woman2
    Gillenormand
    Magnon
    MlleGillenormand
    MmePontmercy
    MlleVaubois
    LtGillenormand
    BaronessT
    Toussaint
Community 5:
    Fauchelevent
    MotherInnocent
    Gribier
Community 6:
    Boulatruelle
Community 7:
    Jondrette
    MmeBurgon
Community 8:
    Gavroche
    Marius
    Mabeuf
    Enjolras
    Combeferre
    Prouvaire
    Feuilly
    Courfeyrac
    Bahorel
    Bossuet
    Joly
    Grantaire
    MmeHucheloup
Community 9:
    MotherPlutarch
Community 10:
    Child1
    Child2