使用 NetworkX 绘制彩色树

Drawing colored trees with NetworkX

注意——这是对上一个问题的完全重写,我认为它太复杂了。它提供了一个更简单的版本,如果我能解决,将会取得进展。

我已经根据这个 SO 答案修改了我的代码:Is there a way to guarantee hierarchical output from NetworkX?

使用以下非常简单的代码,我得到了奇怪的着色行为。

import networkx as nx
import matplotlib.pyplot as plt

G = nx.DiGraph()
G.add_node("ROOT")

for i in xrange(1):
    for j in range(1):
        G.add_node(str(j)+"_%i" % i, )        
        if j ==0:
            G.add_edge("ROOT", str(j)+"_%i" % i)
        else:
            G.add_edge(str(j-1)+"_%i" %i, str(j)+"_%i" % i)

pos=nx.graphviz_layout(G,prog='dot')

for i in xrange(1):
    nodelist = ['ROOT']
    for j in range(1):
        nodelist.append(str(j)+"_%i" % i )
    nx.draw_networkx_nodes(G,pos, nodelist=nodelist, cmap=plt.get_cmap('Set3'), node_color=[0,1])
nx.draw_networkx_edges(G, pos,arrows=True)

limits=plt.axis('off')          

我为 node_color 赋予什么值似乎并不重要,重要的是这些值是否不同。例如,对于 node_color = [0,1],我得到与 [0,.1][0,1000] 时完全相同的行为。 (为什么?颜色图采用 0 到 1 之间的值)。

但是,如果我更改颜色图,颜色就会改变。例如:

如果我设置 node_color = [3,3] (或任何两个相同的值),我总是得到相同的结果,节点的颜色相同。

知道我做错了什么吗?

在获取颜色图之前,节点颜色值被归一化到区间 [0, 1]。这大概意味着要使用所有颜色范围,而不管给定值的范围如何。要使用不同的间隔进行缩放,您可以设置 vminvmax 参数:

nx.draw_networkx_nodes(G,pos, nodelist, cmap=plt.get_cmap('Set3'),
                       node_color=[0,1], vmin=0, vmax=100)



详细解释:

来自node_color参数在draw_networkx_nodes() docs中的描述:

If numeric values are specified they will be mapped to colors using the cmap and vmin,vmax parameters. See matplotlib.scatter for more details.

不幸的是,这些文档没有很好地描述 vminvmax 的行为。但是 reference for matplotlib.scatter 确实涵盖得更全面:

vmin and vmax are used in conjunction with norm to normalize luminance data. If either are None, the min and max of the color array is used.

因此,默认情况下,您传递的 node_color 数组的最小值映射到颜色图上的 0,最大值映射到 1。两者之间的所有内容都映射到区间 [0.0,1.0]使用线性映射(这称为 规范化 feature scaling)。以下是一些示例,从 node_color 到颜色图域中的点:

  • [0, 0.1] → [0, 1]
  • [0, 1000] → [0, 1]
  • [0, 200, 1000] → [0, 0.2, 1]
  • [10, 15, 20] → [0, 0.5, 1]
  • [0, 0] → [0,0] (也可能是[1,1];其实我没有运行这个)