使用matplotlib.colors.Colormap

时间:2017-07-05 21:44:45

标签: python matplotlib plot colors

我正在尝试从给定特定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

2 个答案:

答案 0 :(得分:1)

虽然另一个答案很好地解释了为什么问题的代码失败了,但我想要注意,根本不需要将颜色转换为十六进制,你可以直接使用颜色图来着色图中的点。 / p>

您可以决定循环点并直接将应用的colormap值提供给绘图的color参数。 (中间情节)

或者您可以使用散点图并将plot_arr提供给其c参数以及色彩映射,并在需要时提供规范化。 (右图)

enter image description here

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