我正在尝试从给定特定matplot lib色彩映射的输入标量中获取RGB十六进制字符串。我使用matplotlib.get_cmap()来获取matplotlib.colors.Colormap对象,并将带有范围(0,1)的标量传递给此贴图以获取RGBA值,然后绘制该颜色。但有时绘制的颜色与imshow()绘制的颜色不同。我在这里做些蠢事吗?
繁殖代码
import matplotlib.pyplot as plt
import numpy as np
plt.ioff()
cmap = 'RdBu_r'
cmap = plt.get_cmap(cmap)
f = plt.figure(figsize=(8, 4))
ax1 = f.add_subplot(121)
ax2 = f.add_subplot(122)
plot_arr = np.arange(100).reshape((10, 10)) / 99.
ax1.imshow(plot_arr, vmin=0., vmax=1., cmap=cmap, interpolation='nearest')
for i in range(10):
for j in range(10):
curr_rgb = cmap(plot_arr[i, j])[0:3]
curr_rgb = tuple([int(x * 255) for x in curr_rgb])
r, g, b = curr_rgb
curr_cstr = '#{:0<2}{:0<2}{:0<2}'.format(hex(r)[2:], hex(g)[2:], hex(b)[2:])
ax2.plot(j, i, 'o', mfc=curr_cstr, lw=0, mec='none', ms=20)
ax2.set_xlim([-0.5, 9.5])
ax2.set_ylim([9.5, -0.5])
plt.show()
实际结果
output image
预期结果 如在代码中实现的那样,左图被绘制为imshow()。右图是根据输入标量用colormap对象的颜色绘制的点。如果我的理解是正确的,那么同一网格单元格的颜色应该是相同的。但在高值和低值时明显不同。
Matplotlib版本
操作系统:Windows 7 64位
Matplotlib版本:2.0.2
Python版本:3.5.3
numpy:1.13.0
答案 0 :(得分:1)
虽然另一个答案很好地解释了为什么问题的代码失败了,但我想要注意,根本不需要将颜色转换为十六进制,你可以直接使用颜色图来着色图中的点。 / p>
您可以决定循环点并直接将应用的colormap值提供给绘图的color
参数。 (中间情节)
或者您可以使用散点图并将plot_arr
提供给其c
参数以及色彩映射,并在需要时提供规范化。 (右图)
import matplotlib.pyplot as plt
import numpy as np
cmapname = 'RdBu_r'
cmap = plt.get_cmap(cmapname)
plot_arr = np.arange(100).reshape((10, 10)) / 99.
fig, (ax1,ax2,ax3) = plt.subplots(ncols=3, figsize=(9, 3.5),subplot_kw={"aspect":"equal"})
ax1.set_title("image")
ax1.imshow(plot_arr, vmin=0., vmax=1., cmap=cmap, interpolation='nearest')
ax2.set_title("plot in loop")
for i in range(10):
for j in range(10):
ax2.plot(j, i, 'o', color=cmap(plot_arr[i, j]), lw=0, mec='none', ms=10)
ax2.set_ylim([9.5, -0.5])
ax3.set_title("scatter")
x = np.arange(0,10)
X,Y = np.meshgrid(x,x)
ax3.scatter(X,Y,c=plot_arr, s=100, vmin=0., vmax=1., cmap='RdBu_r', edgecolors="none")
ax3.set_ylim([9.5, -0.5])
plt.show()
答案 1 :(得分:0)
在你的格式化功能中,你左对齐,而不是右对齐,导致奇怪的值跳跃。见这一行:
curr_cstr = '#{:0<2}{:0<2}{:0<2}'.format(hex(r)[2:], hex(g)[2:], hex(b)[2:])
format
的文档。修正版:
import matplotlib.pyplot as plt
import numpy as np
plt.ioff()
cmap = 'RdBu_r'
cmap = plt.get_cmap(cmap)
f = plt.figure(figsize=(8, 4))
ax1 = f.add_subplot(121)
ax2 = f.add_subplot(122)
plot_arr = np.arange(100).reshape((10, 10)) / 99.
ax1.imshow(plot_arr, vmin=0., vmax=1., cmap=cmap, interpolation='nearest')
for i in range(10):
for j in range(10):
curr_rgb = cmap(plot_arr[i, j])[0:3]
curr_rgb = tuple([int(x * 255) for x in curr_rgb])
r, g, b = curr_rgb
curr_cstr = '#{:0>2}{:0>2}{:0>2}'.format(hex(r)[2:], hex(g)[2:], hex(b)[2:])
ax2.plot(j, i, 'o', mfc=curr_cstr, lw=0, mec='none', ms=20)
ax2.set_xlim([-0.5, 9.5])
ax2.set_ylim([9.5, -0.5])
plt.show()
请注意原始内容的RGB到十六进制转换不正确:
if i==9: print i ,j, curr_rgb, curr_cstr
9 0 (170, 21, 41) #001500
9 1 (161, 18, 40) #001200
9 2 (155, 16, 39) #001000
9 3 (147, 14, 38) #00e000
9 4 (138, 11, 36) #00b000
9 5 (132, 9, 35) #009000
9 6 (123, 6, 34) #006000
9 7 (117, 4, 33) #004000
9 8 (108, 1, 31) #001000
9 9 (103, 0, 31) #000000