【问题标题】:Set colors to group of nodes by attribute values in Networkx通过 Networkx 中的属性值将颜色设置为节点组
【发布时间】:2021-01-14 05:07:18
【问题描述】:

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

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 种不同的颜色绘制节点。我尝试了多种方法,但由于我是 NetworkxMatplotlib 的新手,所以没有成功。

【问题讨论】:

    标签: python-3.x matplotlib networkx


    【解决方案1】:

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

    你想要的是,来自nx.draw_networkx documentation

    node_color(颜色或颜色数组(默认='#1f78b4'))- 节点颜色。可以是单一颜色或与节点列表长度相同的颜色序列。颜色可以是字符串,也可以是 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' argument must be a color, a sequence of colours, or a sequence of numbers, not ['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)
    

    如果您的任何节点的node_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")
    

    【讨论】:

    • 我们在此处将列表传递给图形 node_color = 颜色。这个不对。我已经试过了。这是您的代码错误。 ValueError: 'c' argument must be a color, a sequence of colours, or a sequence of numbers, not ['red', 'blue', 'red', 'green', 'green', 'green'... . 它的列表很长。
    • 它应该可以工作,因为它是sequence of colors
    • 我在回答中添加了更多信息,请尝试按原样运行代码,然后根据您的代码进行调整
    • 列表末尾有很多None。所以这可能是问题所在?我想我有很多没有值的节点。让我先弄清楚这个问题。这个我测试这个解决方案。
    • 这就是问题所在!我将发布一个代码以打印 black
    猜你喜欢
    • 1970-01-01
    • 2015-01-17
    • 2016-05-04
    • 2015-05-08
    • 1970-01-01
    • 2019-06-22
    • 2016-04-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多