Python 3.x 在Networkx中按属性值将颜色设置为节点组

Python 3.x 在Networkx中按属性值将颜色设置为节点组,python-3.x,matplotlib,networkx,Python 3.x,Matplotlib,Networkx,我有三种类型的节点(动态绘制的数百或数千个节点) 1-动物 2-树 3-人类 我从JSON文件中读取值,并使用未知值动态创建节点 我想按类型给它们上色。因此,我分配了一个nodetype属性来标识 这是我的节点代码 G.add_node(HumanID, nodetype="red", UserName=userName) G.add_node(TreeID, nodetype="green", BranchName=branchName) G.add_n

我有三种类型的节点(动态绘制的数百或数千个节点)

1-动物 2-树 3-人类

我从JSON文件中读取值,并使用未知值动态创建节点

我想按类型给它们上色。因此,我分配了一个
nodetype
属性来标识

这是我的节点代码

G.add_node(HumanID, nodetype="red", UserName=userName)
G.add_node(TreeID, nodetype="green", BranchName=branchName)
G.add_node(AnimalID, nodetype="blue", AName=aName)
并获取值

colors = set(nx.get_node_attributes(G,'nodetype').values())
print(colors)
输出:
{'green','red','blue'}

我知道这不对,但我想要这样的东西

nx.draw(G,  node_color= colors)

因此,它应该用3种不同的颜色绘制节点。我尝试了多种方法,但由于我对
Networkx
Matplotlib
是新手,因此没有成功。

使用
nx为图形着色时,绘制
关键是保持
颜色的顺序与节点顺序相同
所以使用集合是不行的,因为它们是无序的,不允许重复值

相反,您想要的是:

节点颜色(颜色或颜色数组(默认值为“#1f78b4”)–节点颜色。可以是单色,也可以是与节点列表长度相同的颜色序列。颜色可以是字符串,也可以是从0到1的浮点的rgb(或rgba)元组。如果指定了数值,则将使用cmap和vmin、vmax参数将其映射到颜色。有关详细信息,请参见matplotlib.scatter

<如果我们考虑一个列表,我们可以得到<代码>颜色< /代码>:
colors=[u[1]表示G.nodes中的u(data=“nodetype”)]
以下是一个例子:
G=nx.Graph()
G.添加节点(1,nodetype=“红色”)
G.add_节点(2,nodetype=“蓝色”)
G.add_节点(3,nodetype=“绿色”)
G.add_节点(4,nodetype=“红色”)
G.添加_边(1,3)
G.添加_边(2,4)
G.添加_边(2,3)
颜色=[u[1]表示G.nodes中的u(data=“nodetype”)]
nx.draw(G,带_标签=真,节点_颜色=颜色)
绘制:


编辑:

有一件事可能会导致您的问题: 添加带有
nodetype=“not\u a\u color”
的节点:

这会产生与您得到的错误相同的错误:

ValueError:“c”参数必须是颜色、颜色序列或数字序列,而不是['red'、'blue'、'green'、'not_a_color']

当然,如果您有一个很长的列表,则更难检查。
尝试运行以下命令,以检查是否存在既不是“红色”、“绿色”也不是“蓝色”的颜色

如果节点的
node\u type
属性中有
None
,则将以黑色打印这些节点:

#(change *colors* to):

colors = []
for u in G.nodes(data="nodetype"):
    if u[1] in ("red", "green", "blue"):
        colors.append(u[1])
    elif u[1] == None:
        colors.append("black")
    else:
        #do something?
        print("ERROR: Should be red, green, blue or None")

我们将列表传递到此处的图形节点\u color=colors。这是不对的。我已经试过了。这是您的代码错误。ValueError:“c”参数必须是颜色、颜色序列或数字序列,而不是['red'、'blue'、'red'、'green'、'green'、'green'……这是一个很长的列表。它应该可以工作,因为它是一个
颜色序列
我已经在我的答案中添加了一些更多的信息。请尝试按原样运行代码,然后根据您的需要调整它。请检查它所做的最后一次编辑。接受答案
colors = [u[1] for u in G.nodes(data="nodetype")]

not_colors = [c for c in colors if c not in ("red", "green", "blue")]
if not_colors:
    print("TEST FAILED:", not_colors)
#(change *colors* to):

colors = []
for u in G.nodes(data="nodetype"):
    if u[1] in ("red", "green", "blue"):
        colors.append(u[1])
    elif u[1] == None:
        colors.append("black")
    else:
        #do something?
        print("ERROR: Should be red, green, blue or None")