Python 长度为4数组的Matplotlib colormap错误

Python 长度为4数组的Matplotlib colormap错误,python,numpy,matplotlib,colormap,Python,Numpy,Matplotlib,Colormap,我有一些数组,我需要用一个特定的颜色映射在一个循环中绘制。但是,我的一个数组是length-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,

我有一些数组,我需要用一个特定的颜色映射在一个循环中绘制。但是,我的一个数组是length-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()

看起来您在处理
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()

哦,真讨厌!为长度为3的数组指定RGB颜色元组时也会出现相同的问题。也许一个稍微干净一点的解决方法是使用将RGB(a)元组转换为十六进制字符串。@ali\m当您的评论出现时,我正在处理这个问题
rgb2hex
将使它更简单——谢谢@WarrenWeckesser很棒,这两个选项都很棒而且简单…我最终选择了
rgb2hex
。顺便说一句,它同时接受RGB和RGBA值,因此无需提供
alpha
rgb2hex
接受RGBA值,但它忽略alpha通道;e、 g.
rgb2hex([1.0,0.5,0.25,0.5])
返回
'#ff8040'
。通过关键字参数设置
alpha=
仍然不是完美的,因为它还会影响标记边缘的不透明度。我真的想不出一个简单的方法来解决这个问题。哦,真讨厌!为长度为3的数组指定RGB颜色元组时也会出现相同的问题。也许一个稍微干净一点的解决方法是使用将RGB(a)元组转换为十六进制字符串。@ali\m当您的评论出现时,我正在处理这个问题
rgb2hex
将使它更简单——谢谢@WarrenWeckesser很棒,这两个选项都很棒而且简单…我最终选择了
rgb2hex
。顺便说一句,它同时接受RGB和RGBA值,因此无需提供
alpha
rgb2hex
接受RGBA值,但它忽略alpha通道;e、 g.
rgb2hex([1.0,0.5,0.25,0.5])
返回
'#ff8040'
。通过关键字参数设置
alpha=
仍然不是完美的,因为它还会影响标记边缘的不透明度。不过,我真的想不出一个简单的方法来解决这个问题。