2017-04-21 74 views

回答

5

的文檔networkx.draw_networkx_nodesnetworkx.draw_networkx_edges介紹如何設置節點和邊緣顏色。可以通過找到每個社區的節點位置,然後繪製包含所有位置(然後是一些)的補丁(例如matplotlib.patches.Circle)來製作圍繞社區的補丁。

硬性位是圖形佈局/設置節點位置。 AFAIK,networkx中沒有例行程序來實現所需的圖形佈局「開箱即用」。你想要做的是以下幾點:

1)定位社區之間的相互關係:創建一個新的加權圖,其中每個節點對應一個社區,權重對應於社區之間的邊數。用您最喜歡的圖形佈局算法獲得體面的佈局(例如spring_layout)。

2)定位每個社區中的節點:爲每個社區創建一個新圖。找到子圖的佈局。

3)合併1)和3)中的節點位置。例如。以1)計算的大規模社區職位的10倍;將這些值添加到該社區中所有節點的位置(如2中計算))。

我一直想實現這一段時間。我可能會在今天晚些時候或週末做。

編輯:

瞧。現在你只需要在節點周圍(後面)繪製你最喜歡的補丁。

Output of test()

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/[email protected] 
    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=partition.values()); plt.show() 
    return 
+0

哇!這是個好主意。感謝您的實施 – fullOfQuestion