简体   繁体   English

如何在Networkx中绘制具有社区结构的小图

[英]How to draw a small graph with community structure in networkx

The graph has around 100 nodes, and the number of communities ranges from 5 to 20. Is there any way to draw the graph such that the nodes of the same community are close to each other? 该图有大约100个节点,社区的数目从5到20。是否有任何方法可以绘制该图,以使同一社区的节点彼此靠近?

I've tried to assign different communities different colors, but that does not work well in my application. 我尝试为不同的社区分配不同的颜色,但是在我的应用程序中效果不佳。

I've read this and this but did not find a good solution. 我读过这个这个 ,但没有找到一个好的解决办法。

I'm using python 2.7.12 and newtorkx-1.11 我正在使用python 2.7.12和newtorkx-1.11

For small graph, I find the spring_layout pretty OK for drawing communities. 对于小图,我发现spring_layout对于绘图社区来说还可以。 If you need to highlight nodes (and their communities) I recommend you: 如果您需要突出显示节点(及其社区),我建议您:

  • choose different colors for different communities (the more the colors differ visually, the better), 为不同的社区选择不同的颜色(颜色在视觉上越多越好),

  • increase the size of nodes and 增加节点的大小并

  • make the edges a lighter gray (this way the graph looks less cluttered and the nodes are more highlighted visually). 将边缘设置为较浅的灰色(通过这种方式,图形看起来不那么混乱,节点在视觉上更加突出)。

If you choose spring_layout you can additionally play around with the k argument (the documentation states: Increase this value to move nodes farther apart ). 如果选择spring_layout ,则可以另外使用k参数(文档指出: 增加此值可将节点移得更远 )。 Note that spring_layout can give different images for each time you run the code (this way you can run the code multiple times and save the image only when you're satisfied with the result). 请注意,每次运行代码时spring_layout可以提供不同的图像(通过这种方式,您可以多次运行代码并仅在对结果满意的情况下保存图像)。

In the following example I use a default graph ( nx.karate_club_graph ) in which I detect the communities automatically with the python-louvain package (imported as community ). 在下面的示例中,我使用默认图( nx.karate_club_graph ),在其中使用python-louvain包(导入为community )自动检测community Node sized are defined with the node_size argument in nx.draw_networkx_nodes . 节点的大小与定义node_size在争论nx.draw_networkx_nodes The node colors depend on the community to which they belong -- I use the plt.cm.RdYlBu color map (see more color maps here ). 节点颜色取决于它们所属的社区-我使用plt.cm.RdYlBu颜色图(请参阅此处的更多颜色图)。 Note that you can also affect node sizes (and edges lengths) by defining a bigger or smaller image with figsize in plt.figure . 请注意,您还可以通过在plt.figure使用figsize定义更大或更小的图像来影响节点大小(和边缘长度)。

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)

Output (I ran the code multiple times and choosed the "prettiest" image): 输出(我多次运行该代码并选择了“最精美”的图像):

在此处输入图片说明

But what if you have a bigger graph with less obvious communities? 但是,如果您有一个较大的图表,而社区却不那么明显怎么办? Here is a more complicated graph with 100 nodes and 100 random edges (and thus random communities) but with the same drawing approach: 这是一个更复杂的图形,具有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)

Output: 输出:

在此处输入图片说明

We see no clear communities in the image above. 我们在上图中看不到清晰的社区。 Here you have at least three choices: 在这里,您至少有三个选择:

  • define the graph layout (nodes coordinates/positions) manually ( pos in my code), 手动定义图形布局(节点坐标/位置)(在我的代码中为pos ),

  • experiment with different layouts (found here ) and 试验不同的布局(在此处找到),并

  • have an image for each community (or at least the most important communities). 对每个社区(或至少是最重要的社区)都有一个形象。

If you choose the third option, you can have the nodes of one highlighted community bigger than other nodes (and of different color of course). 如果选择第三个选项,则可以使一个突出显示的社区的节点大于其他节点(当然也可以具有不同的颜色)。 You could also change the color and thickness of edges in that community (not shown in the example below). 您还可以更改该社区中边缘的颜色和厚度(在下面的示例中未显示)。

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)

Output (only the first community highlighted): 输出(仅突出显示第一个社区):

在此处输入图片说明

If you have multiple images for the same graph, I recommend that the nodes have the same positions in all of them (you'll need to have the same pos between drawings). 如果您有相同的图形多张图片,我建议节点在所有的人都在相同的位置(你需要有相同的pos图纸之间)。 That way the images are more comparable. 这样,图像更具可比性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM