答案 0 :(得分:8)
networkx.draw_networkx_nodes
和networkx.draw_networkx_edges
的文档说明了如何设置节点和边缘颜色。可以通过找到每个社区的节点位置然后绘制包含所有位置(然后是一些位置)的补丁(例如matplotlib.patches.Circle
)来制作界定社区的补丁。
硬位是图形布局/设置节点位置。 AFAIK,在networkx中没有例程来实现所需的图形布局"开箱即用"。你想要做的是以下几点:
1)相对于彼此定位社区:创建一个新的加权图,其中每个节点对应一个社区,权重对应于社区之间的边数。使用您喜欢的图形布局算法(例如spring_layout
)获得合适的布局。
2)定位每个社区内的节点:对于每个社区,创建一个新图。找到子图的布局。
3)在1)和3)中组合节点位置。例如。规模社区位置在1)中计算10倍;将这些值添加到该社区内所有节点的位置(如2中计算)。
我一直希望实现这一点。我可能会在今天晚些时候或周末这样做。
瞧。现在你只需要在节点周围(后面)绘制你最喜欢的补丁。
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=partition.values()); plt.show()
return