Matplotlib 程序中的误区

Misunderstanding in a Matplotlib program

我正在使用 Matplotlib 3.1.1

编写代码“作为水平条形图的离散分布”,可在此处找到 LINK

绕着这个问题转了半天,还是想不通:指令是什么意思:category_colors = plt.get_cmap('RdYlGn')(np.linspace(0.15, 0.85, data.shape[1])) ?

由于 np.linspace(0.15, 0.85, data.shape[1]) 解析为 array([0.15 , 0.325, 0.5 , 0.675, 0.85 ]),我首先认为该程序正在使用 colormap RdYlGn(应该从 color=0.0 到 color=1.0)然后取位于点0.15的5种特定颜色,依此类推,0.85

但是,打印 category_colors 解析为 (5, 4) array:

array([[0.89888504, 0.30549789, 0.20676663, 1.        ],
       [0.99315648, 0.73233372, 0.42237601, 1.        ],
       [0.99707805, 0.9987697 , 0.74502115, 1.        ],
       [0.70196078, 0.87297193, 0.44867359, 1.        ],
       [0.24805844, 0.66720492, 0.3502499 , 1.        ]])

我不明白这些数字指的是什么???

plt.get_cmap('RdYlGn') returns 一个将 0 到 1 之间的数字映射到相应颜色的函数,其中 0 映射到红色,0.5 映射到黄色,1 映射到绿色。通常,此函数的名称为 cmap = plt.get_cmap('RdYlGn')。然后 cmap(0)(与 plt.get_cmap('RdYlGn')(0) 相同)将是 (red, green, blue, alpharbga-value (0.6470588235294118, 0.0, 0.14901960784313725, 1.0))。在十六进制中,此颜色为 #a50026.

通过 numpy 的 broadcasting 魔法,cmap(np.array([0.15 , 0.325, 0.5 , 0.675, 0.85 ])) 得到与 np.array([cmap(0.15), cmap(0.325), ..., cmap(0.85)]) 相同的结果。 (换句话说,许多 numpy 函数应用于一个数组 return 该函数的数组应用于各个元素。)

因此,category_colors = cmap(np.linspace(0.15, 0.85, 5)) 的第一行将是与值 0.150.89888504, 0.30549789, 0.20676663, 1. 对应的颜色的 rgba 值。这是一种含有 90% 红色、31% 绿色和 21% 蓝色(并且 alpha=1 表示完全不透明)的颜色,非常偏红。下一行是0.325对应的rgba值,依此类推

下面是一些代码来说明这些概念:

import matplotlib.pyplot as plt
from matplotlib.colors import to_hex  # convert a color to hexadecimal format
from matplotlib.cm import ScalarMappable  # needed to create a custom colorbar
import numpy as np

cmap = plt.get_cmap('RdYlGn')
color_values = np.linspace(0.15, 0.85, 5)
category_colors = cmap(color_values)
plt.barh(color_values, 1, height=0.15, color=category_colors)
plt.yticks(color_values)
plt.colorbar(ScalarMappable(cmap=cmap), ticks=color_values)
plt.ylim(0, 1)
plt.xlim(0, 1.1)
plt.xticks([])
for val, color in zip(color_values, category_colors):
    r, g, b, a = color
    plt.text(0.1, val, f'r:{r:0.2f} g:{g:0.2f} b:{b:0.2f} a:{a:0.1f}\nhex:{to_hex(color)}', va='center')
plt.show()

PS:您可能还想阅读有关 norms 的内容,它将任意范围映射到颜色映射使用的范围 0,1。