首页 > 解决方案 > 通过 Networkx 中的属性值将颜色设置为节点组

问题描述

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

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没有成功。

标签: python-3.xmatplotlibnetworkx

解决方案


使用nx.draw它为图形着色时,关键是要保持与colors节点顺序相同的顺序
所以使用集合是行不通的,因为它们是无序的并且不允许重复值。

相反,您想要的是,来自nx.draw_networkx文档

node_color(颜色或颜色数组(默认='#1f78b4'))–节点颜色。可以是一种颜色,也可以是与 nodelist 长度相同的颜色序列。颜色可以是字符串,也可以是 0-1 的浮点数的 rgb(或 rgba)元组。如果指定了数值,它们将使用 cmap 和 vmin,vmax 参数映射到颜色。有关更多详细信息,请参见 matplotlib.scatter。

因此,如果我们考虑一个列表,我们可以colors这样获得:

colors = [u[1] for u in G.nodes(data="nodetype")]

这是一个例子:

G=nx.Graph()

G.add_node(1, nodetype="red")
G.add_node(2, nodetype="blue")
G.add_node(3, nodetype="green")
G.add_node(4, nodetype="red")
G.add_edge(1, 3)
G.add_edge(2, 4)
G.add_edge(2, 3)

colors = [u[1] for u in G.nodes(data="nodetype")]
nx.draw(G, with_labels =True, node_color = colors)

抽奖:
示例结果


编辑:

可能导致您遇到的问题的一件事:

添加一个节点nodetype="not_a_color"

G.add_node(4, nodetype="not_a_color")
colors = [u[1] for u in G.nodes(data="nodetype")]
nx.draw(G, with_labels =True, node_color = colors)

这给出了与您得到的相同的错误:

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

当然,如果您的清单很长,则更难以检查。
尝试运行以下命令,以检查是否有两种颜色都不是"red""green"或者"blue"

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)

如果您有None任何节点的node_type属性,这将以黑色打印这些节点:

#(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")

推荐阅读