我有一个我想要绘制的 2d numpy 数组,这样我就可以看到每个类别在网格上的位置。矩阵 (mat) 看起来像这样:
156 138 156
1300 137 156
138 138 1300
137 137 137
我画的是这样的:
plt.imshow(mat, cmap='tab20', interpolation='none')
但是,我想要自定义颜色。我有一个 csv,其中 id 对应于矩阵中的值:
id,R,G,B
156,200,200,200
138,170,255,245
137,208,130,40
1300,63,165,76
有没有办法让矩阵中的值与 csv 文件中的 R、G、B 值相对应?
编辑:有人要求澄清,但整个答案都被删除了。
每一行都有一个 ID 和一个 3 列,代表各自的 R、G 和 B 值。所以第一行有 ID 156(域特定代码)和 R 200、G 200 和 B 200(灰色)。
现在我有一个要绘制的二维矩阵,在值为 156 的每个坐标上,我希望该像素为灰色。与 ID 1300 相同,其中颜色 63、165 和 76 代表我想在矩阵中使用的绿色。
最佳答案
使用颜色图
原则上,具有 RGB 值的矩阵是某种颜色图。在 matplotlib 中使用颜色图来获取绘图的颜色是有意义的。使这变得有点复杂的是这些值没有很好地间隔。所以一个想法是首先将它们映射到从 0 开始的整数。然后从这些值创建一个颜色图并将其与 BoundaryNorm 一起使用允许有一个等距的颜色条。最后,可以将颜色条的标记标签设置回初始值。
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors
a =np.array([[156, 138, 156],
[1300, 137, 156],
[138, 138, 1300],
[137, 137, 137]])
ca = np.array([[156,200,200,200],
[138,170,255,245],
[137,208,130,40],
[1300,63,165,76]])
u, ind = np.unique(a, return_inverse=True)
b = ind.reshape((a.shape))
colors = ca[ca[:,0].argsort()][:,1:]/255.
cmap = matplotlib.colors.ListedColormap(colors)
norm = matplotlib.colors.BoundaryNorm(np.arange(len(ca)+1)-0.5, len(ca))
plt.imshow(b, cmap=cmap, norm=norm)
cb = plt.colorbar(ticks=np.arange(len(ca)))
cb.ax.set_yticklabels(np.unique(ca[:,0]))
plt.show()
绘制 RGB 数组
您可以从您的数据创建一个 RGB 数组以直接绘制为 imshow
。为此,您可以使用颜色数组中的颜色为原始数组编制索引,并重新调整生成的数组的形状,使其处于正确的形状以使用 imshow 绘制。
import numpy as np
import matplotlib.pyplot as plt
a =np.array([[156, 138, 156],
[1300, 137, 156],
[138, 138, 1300],
[137, 137, 137]])
ca = np.array([[156,200,200,200],
[138,170,255,245],
[137,208,130,40],
[1300,63,165,76]])
u, ind = np.unique(a, return_inverse=True)
c = ca[ca[:,0].argsort()][:,1:]/255.
b = np.moveaxis(c[ind][:,:,np.newaxis],1,2).reshape((a.shape[0],a.shape[1],3))
plt.imshow(b)
plt.show()
结果与上面相同,但没有颜色条(因为这里没有要映射的数量)。
关于python - 使用自定义颜色绘制 2d numpy 数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47776318/