如何使用networkx绘制社区 [英] how to draw communities with networkx

查看:460
本文介绍了如何使用networkx绘制社区的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何使用python networkx这样的图绘制社区图:

How can I draw a graph with it's communities using python networkx like this image :

图像网址

推荐答案

networkx.draw_networkx_nodesnetworkx.draw_networkx_edges的文档介绍了如何设置节点和边缘颜色.可以通过找到每个社区的节点位置,然后绘制包含所有位置(然后是某些位置)的补丁(例如matplotlib.patches.Circle)来制作包围社区的补丁.

The documentation for networkx.draw_networkx_nodes and networkx.draw_networkx_edges explains how to set the node and edge colors. The patches bounding the communities can be made by finding the positions of the nodes for each community and then drawing a patch (e.g. matplotlib.patches.Circle) that contains all positions (and then some).

最困难的是图形布局/设置节点位置. AFAIK,networkx中没有例程可以开箱即用"地实现所需的图形布局.您要执行的操作如下:

The hard bit is the graph layout / setting the node positions. AFAIK, there is no routine in networkx to achieve the desired graph layout "out of the box". What you want to do is the following:

1)相对于社区定位社区:创建一个新的加权图,其中每个节点对应一个社区,权重对应于社区之间的边数.使用您最喜欢的图形布局算法(例如spring_layout)获得一个体面的布局.

1) Position the communities with respect to each other: create a new, weighted graph, where each node corresponds to a community, and the weights correspond to the number of edges between communities. Get a decent layout with your favourite graph layout algorithm (e.g.spring_layout).

2)将节点放置在每个社区中:为每个社区创建一个新图.查找子图的布局.

2) Position the nodes within each community: for each community, create a new graph. Find a layout for the subgraph.

3)合并1)和3)中的节点位置.例如.将1)中计算出的社区职位规模扩大10倍;将这些值添加到该社区内所有节点的位置(按2计算).

3) Combine node positions in 1) and 3). E.g. scale community positions calculated in 1) by a factor of 10; add those values to the positions of all nodes (as computed in 2)) within that community.

我一直想实现这一点.我可能会在今天晚些时候或周末这样做.

Voila.现在,您只需要在节点周围(后面)绘制自己喜欢的补丁.

Voila. Now you just need to draw your favourite patch around (behind) the nodes.

import numpy as np
import matplotlib.pyplot as plt
import networkx as nx

def community_layout(g, partition):
    """
    Compute the layout for a modular graph.


    Arguments:
    ----------
    g -- networkx.Graph or networkx.DiGraph instance
        graph to plot

    partition -- dict mapping int node -> int community
        graph partitions


    Returns:
    --------
    pos -- dict mapping int node -> (float x, float y)
        node positions

    """

    pos_communities = _position_communities(g, partition, scale=3.)

    pos_nodes = _position_nodes(g, partition, scale=1.)

    # combine positions
    pos = dict()
    for node in g.nodes():
        pos[node] = pos_communities[node] + pos_nodes[node]

    return pos

def _position_communities(g, partition, **kwargs):

    # create a weighted graph, in which each node corresponds to a community,
    # and each edge weight to the number of edges between communities
    between_community_edges = _find_between_community_edges(g, partition)

    communities = set(partition.values())
    hypergraph = nx.DiGraph()
    hypergraph.add_nodes_from(communities)
    for (ci, cj), edges in between_community_edges.items():
        hypergraph.add_edge(ci, cj, weight=len(edges))

    # find layout for communities
    pos_communities = nx.spring_layout(hypergraph, **kwargs)

    # set node positions to position of community
    pos = dict()
    for node, community in partition.items():
        pos[node] = pos_communities[community]

    return pos

def _find_between_community_edges(g, partition):

    edges = dict()

    for (ni, nj) in g.edges():
        ci = partition[ni]
        cj = partition[nj]

        if ci != cj:
            try:
                edges[(ci, cj)] += [(ni, nj)]
            except KeyError:
                edges[(ci, cj)] = [(ni, nj)]

    return edges

def _position_nodes(g, partition, **kwargs):
    """
    Positions nodes within communities.
    """

    communities = dict()
    for node, community in partition.items():
        try:
            communities[community] += [node]
        except KeyError:
            communities[community] = [node]

    pos = dict()
    for ci, nodes in communities.items():
        subgraph = g.subgraph(nodes)
        pos_subgraph = nx.spring_layout(subgraph, **kwargs)
        pos.update(pos_subgraph)

    return pos

def test():
    # to install networkx 2.0 compatible version of python-louvain use:
    # pip install -U git+https://github.com/taynaud/python-louvain.git@networkx2
    from community import community_louvain

    g = nx.karate_club_graph()
    partition = community_louvain.best_partition(g)
    pos = community_layout(g, partition)

    nx.draw(g, pos, node_color=list(partition.values())); plt.show()
    return

这篇关于如何使用networkx绘制社区的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆