生成聚类图 ¶
生成聚类图¶
此示例展示了如何在一个图中找到社群,然后使用 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 值的平均值,以便聚类图中的节点位于原始聚类位置的中心。
注意
mean
,first
和 sum
都是内置的折叠函数,以及 prod
,median
,max
,min
,last
,random
。您还可以定义自己的自定义折叠函数,该函数接收一个列表并返回一个表示组合属性值的单个元素。有关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)
这里并排显示了两个图
……我们打印出的社群的最终输出显示在下方
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