是否可以使用networkx为每个节点绘制具有多种颜色的图形 [英] Is it possible to draw a graph with multiple color for each node with networkx

查看:152
本文介绍了是否可以使用networkx为每个节点绘制具有多种颜色的图形的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想为空手道俱乐部图的节点和边缘着色.但是某些节点具有不止一种颜色.有什么方法可以在python中(尤其是使用networkx)为节点着色上一种以上的颜色?我需要这样的东西:

解决方案

可以完成此操作,但可能需要大量工作才能获得所需的确切结果.您可以从

编辑

嗯,这有点像我了,我真的很想做出与您发布的内容类似的内容.这是我想出的:

 #编码:utf-8将networkx导入为nx导入itertools从馆藏进口柜台def edge_in_com(节点,图):边= []对于itertools.combinations(nodes,2)中的(i,j):如果graph.edges()中的(i,j):edges.append((i,j))返回边缘空手道= nx.generators.social.karate_club_graph()karate_agr = nx.nx_agraph.to_agraph(空手道)karate_agr.graph_attr ['dpi'] = 180karate_agr.edge_attr.update(dir ='both',arrowhead ='inv',arrowtail ='inv',penwidth = 2.0)karate_agr.node_attr.update(样式=已填充",fontcolor ='white',形状=圆形",color ='transparent',渐变角度= 90)颜色= [灰色",粉红色",蓝色",紫色"]社区=列表(nx.community.asyn_fluidc(空手道,4))most_edges = []对于n,com的枚举(社区):edges = edge_in_com(com,空手道)most_edges.extend(edges)对于边缘中的边缘:e = karate_agr.get_edge(* edge)e.attr ['color'] =颜色[n]对于com中的节点:节点= karate_agr.get_node(节点)node.attr ['fillcolor'] =颜色[n]其他= [如果e在most_edges中,则e在karate.edges()中为e)在其他方面的优势:gn = karate_agr.get_nodecolor = gn(edge [0]).attr ['fillcolor']karate_agr.get_edge(* edge).attr ['color'] =颜色对于karate_agr.nodes()中的n:cls = [e.attr ['color'] for karate_agr.in_edges(n)中的e]cls2 = [e.attr ['color'] for karate_agr.out_edges(n)中的e]cls = set(cls + cls2)如果len(cls)>1:#如果n.attr ['fillcolor']!= cls [0]:color1 = cls.pop()color2 = cls.pop()color_mix =''.join([[color1,';','0.5:',color2])n.attr ['fillcolor'] = color_mixkarate_agr.draw('karate.png',prog ='neato') 

该程序肯定可以改进,我对结果仍然不满意,但也许会对您有所帮助.

I want to color nodes and edges of Karate club graph. But some of nodes have more than one color. Is there any way to color a node with more than one color in python (especially with networkx)? I need something like this:

解决方案

This can be done but it will probably require a lot of work to obtain the exact result you want. You could start with networkx and pygraphviz like this:

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')

Pygraphviz makes use of graphviz which has really a lot of options. Most of them can be set either for individual nodes (or edges) or globally for all of them like in the example above. It is all well explained in the graphviz documentation.

The above snippet only shows how to make the nodes filled half with one color and half with the other. See the result below (not very beautiful, I know).

EDIT

Hmm, so this kinda grew on me, and I really wanted to make something more similar to what you posted. This is what I came up with:

# 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')

The program definitely can be improved, and I'm still not very happy with the results but maybe you'll find it helpful.

这篇关于是否可以使用networkx为每个节点绘制具有多种颜色的图形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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