长度为 4 的数组的 Matplotlib 颜色映射错误

Matplotlib colormap bug with length-4 arrays

我有一些数组需要在具有特定颜色图的循环中绘制。但是,我的一个数组的长度为 4,我 运行 遇到了这个问题:

import numpy as np
import matplotlib as plt

ns = range(2,8)
cm = plt.cm.get_cmap('spectral')
cmap = [cm(1.*i/len(ns)) for i in range(len(ns))]
for i,n in enumerate(ns):
    x = np.linspace(0, 10, num=n)
    y = np.zeros(n) + i
    plt.scatter(x, y, c=cmap[i], edgecolor='none', s=50, label=n)
plt.legend(loc='lower left')
plt.show()

对于 n=4,看起来 Matplotlib 正在将 cmap RGBA 元组的每个元素应用于数组的每个值。对于其他长度数组,行为是预期的。

现在,我的代码实际上要复杂得多,不想花时间重写循环。有解决办法吗?

看来您在处理 c 参数时遇到了一个不幸的 API 设计。解决该问题的一种方法是制作 c 形状为 (len(x), 4) 的数组,其中包含所需颜色的 len(x) 个副本。例如

ns = range(2,8)
cm = plt.cm.get_cmap('spectral')
cmap = [cm(1.*i/len(ns)) for i in range(len(ns))]
for i,n in enumerate(ns):
    x = np.linspace(0, 10, num=n)
    y = np.zeros(n) + i
    c = np.tile(cmap[i], (len(x), 1))
    plt.scatter(x, y, c=c, edgecolor='none', s=50, label=n)
plt.legend(loc='lower left')
plt.show()

另一种方法是将 RBG 值转换为十六进制字符串,并使用 alpha 参数传递颜色的 alpha 通道。正如@ali_m 在评论中指出的那样,函数 matplotlib.colors.rgb2hex 使这变得容易。如果您知道颜色的 Alpha 通道始终为 1.0,则可以删除创建 alpha 参数的代码。

import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt

ns = range(2,8)
cm = plt.cm.get_cmap('spectral')
cmap = [cm(1.*i/len(ns)) for i in range(len(ns))]
for i,n in enumerate(ns):
    x = np.linspace(0, 10, num=n)
    y = np.zeros(n) + i
    c = mpl.colors.rgb2hex(cmap[i])
    alpha = cmap[i][3]
    plt.scatter(x, y, c=c, edgecolor='none', s=50, label=n, alpha=alpha)
plt.legend(loc='lower left')
plt.show()