生成聚类图

此示例展示了如何在一个图中找到社区,然后使用 igraph.clustering.VertexClustering 将每个社区收缩成一个单一节点。在本教程中,我们将使用唐纳德·克努特的《悲惨世界》网络,该网络显示了小说《悲惨世界》中人物的共同出现。

import igraph as ig
import matplotlib.pyplot as plt

我们首先从文件中加载图。包含此网络的文件可从此处下载。

g = ig.load("./lesmis/lesmis.gml")

现在图中已加载到内存中,我们可以使用 igraph.Graph.community_edge_betweenness() 生成社区,将顶点分离成聚类。(有关仅可视化社区的更集中教程,请查看社区)。

对于绘图,将社区转换为 VertexClustering 很方便

我们还可以轻松打印出每个社区的成员

for i, community in enumerate(communities):
    print(f"Community {i}:")
    for v in community:
        print(f"\t{g.vs[v]['label']}")
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

最后,我们可以开始绘制图。为了使每个社区突出显示,我们使用 igraph 调色板设置了“社区颜色”

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"]]

最后,我们可以绘制社区

fig1, ax1 = plt.subplots()
ig.plot(
    communities,
    target=ax1,
    mark_groups=True,
    palette=palette1,
    vertex_size=15,
    edge_width=0.5,
)
fig1.set_size_inches(20, 20)
cluster contraction

现在让我们尝试收缩信息,仅使用一个顶点来表示每个社区。我们首先为原始图中的每个节点定义 x、y 和大小属性

layout = g.layout_kamada_kawai()
g.vs["x"], g.vs["y"] = list(zip(*layout))
g.vs["size"] = 15
g.es["size"] = 15

然后,我们可以使用 igraph.VertexClustering.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 收缩的更多详细信息,请参阅 igraph.GraphBase.contract_vertices()

最后,我们可以为聚类分配颜色并绘制聚类图,包括一个图例以使内容清晰。

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(20, size) 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)
cluster contraction

脚本总运行时间: (0 分钟 0.955 秒)

此图库由 Sphinx-Gallery 生成