如何在networkx中绘制带有社区结构的小图

7
图中有大约100个节点,社区数量从5到20不等。是否有办法绘制图形,使同一社区的节点彼此靠近?
我尝试给不同的社区分配不同的颜色,但在我的应用程序中效果不佳。
我已经阅读了thisthis,但没有找到一个好的解决方案。
我正在使用Python 2.7.12和Newtorkx-1.11。
1个回答

12
对于小型图,我发现spring_layout非常适合绘制社区。如果你需要突出节点(和它们所属的社区),我建议你:
  • 选择不同颜色的不同社区(颜色越不同,就越好)

  • 增加节点的大小

  • 将边缘设为浅灰色(这样图表看起来更整洁,节点在视觉上更加突出)。

如果你选择了 spring_layout ,你还可以通过调整 k 参数进行实验(文档中写到:增大此值可使节点相距更远)。请注意,spring_layout 每次运行代码都会给出不同的图像(这样你就可以多次运行代码,并仅在满意结果时保存图像)。

在下面的示例中,我使用默认图 (nx.karate_club_graph ),并使用python-louvain 包(导入为community )自动检测社区。节点大小是用nx.draw_networkx_nodes 中的node_size 参数定义的。节点颜色取决于它们所属的社区-我使用plt.cm.RdYlBu 颜色映射(在这里可以看到更多颜色映射)。请注意,你还可以通过在plt.figure 中定义更大或更小的图像来影响节点大小(和边缘长度)。

import networkx as nx
import community
import matplotlib.pyplot as plt

G = nx.karate_club_graph()  # load a default graph

partition = community.best_partition(G)  # compute communities

pos = nx.spring_layout(G)  # compute graph layout
plt.figure(figsize=(8, 8))  # image is 8 x 8 inches
plt.axis('off')
nx.draw_networkx_nodes(G, pos, node_size=600, cmap=plt.cm.RdYlBu, node_color=list(partition.values()))
nx.draw_networkx_edges(G, pos, alpha=0.3)
plt.show(G)

输出结果(我运行了多次代码并选择了“最美”的图像):

enter image description here

但是如果你有一个更大的图形,而且社区不太明显怎么办?这里有一个更复杂的图形,有100个节点和100个随机边(因此有随机社区),但采用相同的绘图方法:

import networkx as nx
import community
import matplotlib.pyplot as plt
import random

H = nx.Graph()

nodes = list(range(100))  # 100 nodes

# add 100 random edges
for i in range(100):
    src = random.choice(nodes)
    dest = random.choice(nodes)
    # we don't want src to be the same as dest
    while src == dest:
        dest = random.choice(nodes)

    H.add_edge(src, dest)

partition = community.best_partition(H)  # compute communities

pos = nx.spring_layout(H)  # compute graph layout
plt.figure(figsize=(10, 10))
plt.axis('off')
nx.draw_networkx_nodes(H, pos, node_size=600, cmap=plt.cm.RdYlBu, node_color=list(partition.values()))
nx.draw_networkx_edges(H, pos, alpha=0.3)
plt.show(H)

输出:

在此输入图片描述

从上图中我们无法看出清晰的社区。以下是你至少可以选择三种方法:

  • 手动定义图形布局(节点坐标/位置) (pos 在我的代码中),

  • 尝试使用不同的布局方式 (可在这里找到) 以及

  • 为每个社区准备一张图片 (或者至少是最重要的社区)。

如果您选择第三个选项,您可以将一个突出显示的社区的节点比其他节点更大(当然也是不同颜色)。您还可以改变该社区中边缘的颜色和粗细(在下面的示例中未显示)。

node_size = []

# first community against the others
for node, community in partition.items():
    if community == 1:
        node_size.append(900)
    else:
        partition[node] = 0  # I put all the other communities in one communitiy
        node_size.append(300)

plt.figure(figsize=(10, 10))
plt.axis('off')
nodes = nx.draw_networkx_nodes(H, pos, node_size=node_size, cmap=plt.cm.winter, node_color=list(partition.values()))
nx.draw_networkx_edges(H, pos, alpha=0.3)
plt.show(H)

输出 (仅突出显示第一个社区):

在此输入图片描述

如果您有多张同一图形的图片,建议所有节点在这些图片中位置相同(需要在绘图之间保持相同的 pos )。这样,这些图片就更加可比较。


这个详细的答案非常有帮助。使用色图使代码更整洁,图形更易于可视化。 - user3813057

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接