use*_*927 2 python graph networkx
我想为空手道俱乐部图的节点和边缘着色。但是有些节点有不止一种颜色。有没有办法在python(尤其是networkx)中用一种以上的颜色为节点着色?我需要这样的东西:
这可以完成,但可能需要大量工作才能获得您想要的确切结果。你可以像这样从networkx 和 pygraphviz开始:
import networkx as nx
karate = nx.generators.social.karate_club_graph()
karate_agr = nx.nx_agraph.to_agraph(karate)
karate_agr.node_attr['style'] = 'filled'
karate_agr.node_attr['shape'] = 'circle'
karate_agr.node_attr['gradientangle'] = 90
for i in karate_agr.nodes():
n = karate_agr.get_node(i)
n.attr['fillcolor'] = 'green;0.5:yellow'
karate_agr.draw('karate.png',prog='dot')
Run Code Online (Sandbox Code Playgroud)
Pygraphviz使用了graphviz,它确实有很多选择。它们中的大多数可以为单个节点(或边)设置,也可以像上面的示例中那样为所有节点全局设置。在graphviz 文档中对这一切都有很好的解释。
上面的代码片段只展示了如何让节点用一种颜色填充一半,用另一种颜色填充一半。看看下面的结果(不是很漂亮,我知道)。
编辑
嗯,所以这对我来说有点增长,我真的很想制作一些与您发布的内容更相似的内容。这就是我想出的:
# coding: utf-8
import networkx as nx
import itertools
from collections import Counter
def edge_in_com(nodes, graph):
edges = []
for (i, j) in itertools.combinations(nodes, 2):
if (i, j) in graph.edges():
edges.append((i, j))
return edges
karate = nx.generators.social.karate_club_graph()
karate_agr = nx.nx_agraph.to_agraph(karate)
karate_agr.graph_attr['dpi'] = 180
karate_agr.edge_attr.update(
dir='both', arrowhead='inv', arrowtail='inv', penwidth=2.0)
karate_agr.node_attr.update(
style='filled',
fontcolor='white',
shape='circle',
color='transparent',
gradientangle=90)
colors = ['grey', 'pink', 'blue', 'purple']
communities = list(nx.community.asyn_fluidc(karate, 4))
most_edges = []
for n, com in enumerate(communities):
edges = edge_in_com(com, karate)
most_edges.extend(edges)
for edge in edges:
e = karate_agr.get_edge(*edge)
e.attr['color'] = colors[n]
for node in com:
node = karate_agr.get_node(node)
node.attr['fillcolor'] = colors[n]
other = [e for e in karate.edges() if e not in most_edges]
for edge in other:
gn = karate_agr.get_node
color = gn(edge[0]).attr['fillcolor']
karate_agr.get_edge(*edge).attr['color'] = color
for n in karate_agr.nodes():
cls = [e.attr['color'] for e in karate_agr.in_edges(n)]
cls2 = [e.attr['color'] for e in karate_agr.out_edges(n)]
cls = set(cls + cls2)
if len(cls) > 1:
# if n.attr['fillcolor'] != cls[0]:
color1 = cls.pop()
color2 = cls.pop()
color_mix = ''.join([color1, ';', '0.5:', color2])
n.attr['fillcolor'] = color_mix
karate_agr.draw('karate.png', prog='neato')
Run Code Online (Sandbox Code Playgroud)
该程序肯定可以改进,我对结果仍然不是很满意,但也许您会发现它有帮助。