Python 更改plt.imshow()图像像素的颜色
我需要用matplotlib的imshow()绘制一幅图像,然后用不同的颜色标记一些像素。仅仅在初始数组中更改它们的值是行不通的,因为我需要使用我正在使用的颜色映射中不存在的颜色。因此,我最初的意图是在第一幅图像上方绘制第二个生成的数组,其中大部分被遮罩,所需的像素没有被遮罩,并且有一些值(可能不同的值会对不同的坐标使用不同的颜色)。它与matplotlib的交互式查看器配合得很好,但是当保存到文件中时,所有内容都会被扭曲,这可能是因为我在相同的情况下报告了这个bug:Python 更改plt.imshow()图像像素的颜色,python,matplotlib,Python,Matplotlib,我需要用matplotlib的imshow()绘制一幅图像,然后用不同的颜色标记一些像素。仅仅在初始数组中更改它们的值是行不通的,因为我需要使用我正在使用的颜色映射中不存在的颜色。因此,我最初的意图是在第一幅图像上方绘制第二个生成的数组,其中大部分被遮罩,所需的像素没有被遮罩,并且有一些值(可能不同的值会对不同的坐标使用不同的颜色)。它与matplotlib的交互式查看器配合得很好,但是当保存到文件中时,所有内容都会被扭曲,这可能是因为我在相同的情况下报告了这个bug: 是否有其他选项可以更改某
是否有其他选项可以更改某些像素的颜色 您已经建议了最简单的方法(在顶部覆盖另一个图像),但是如果这不符合您的要求,还有其他选择
方法#1-手动渲染和合成图像
最直接的方法是使用colormap将阵列渲染为RGB,然后更改所需的像素 举个简单的例子:
import numpy as np
import matplotlib.pyplot as plt
data = np.arange(100).reshape(10, 10)
cmap = plt.cm.gray
norm = plt.Normalize(data.min(), data.max())
rgba = cmap(norm(data))
# Set the diagonal to red...
rgba[range(10), range(10), :3] = 1, 0, 0
plt.imshow(rgba, interpolation='nearest')
plt.show()
import numpy as np
import matplotlib.pyplot as plt
data = np.arange(100).reshape(10, 10)
cmap = plt.cm.gray
norm = plt.Normalize(data.min(), data.max())
rgba = cmap(norm(data))
# Set the diagonal to red
rgba[range(10), range(10), :3] = 1, 0, 0
fig, ax = plt.subplots()
ax.imshow(rgba, interpolation='nearest')
# Add the colorbar using a fake (not shown) image.
im = ax.imshow(data, visible=False, cmap=cmap)
fig.colorbar(im)
plt.show()
此方法的一个缺点是,当您传入预渲染的rgb图像时,不能仅调用fig.colorbar(im)
。因此,如果你需要一个色条,你必须使用一个代理艺术家。最简单的方法是使用imshow(data,visible=False)
添加一个额外的、不可见的(不是绘制的,而是透明的)艺术家,然后将颜色贴图基于该艺术家。举个简单的例子:
import numpy as np
import matplotlib.pyplot as plt
data = np.arange(100).reshape(10, 10)
cmap = plt.cm.gray
norm = plt.Normalize(data.min(), data.max())
rgba = cmap(norm(data))
# Set the diagonal to red...
rgba[range(10), range(10), :3] = 1, 0, 0
plt.imshow(rgba, interpolation='nearest')
plt.show()
import numpy as np
import matplotlib.pyplot as plt
data = np.arange(100).reshape(10, 10)
cmap = plt.cm.gray
norm = plt.Normalize(data.min(), data.max())
rgba = cmap(norm(data))
# Set the diagonal to red
rgba[range(10), range(10), :3] = 1, 0, 0
fig, ax = plt.subplots()
ax.imshow(rgba, interpolation='nearest')
# Add the colorbar using a fake (not shown) image.
im = ax.imshow(data, visible=False, cmap=cmap)
fig.colorbar(im)
plt.show()
使用不可见的imshow
是为此制作代理艺术家的最简单方法,但是如果速度是一个问题(或者如果它以某种方式触发了您提到的渲染错误),您也可以使用任何ScalarMappable
ScalarMapable
是一个抽象基类,通常仅用于继承以支持colorbar。因为我们不需要画任何东西,我们可以直接使用它
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.cm import ScalarMappable
data = np.arange(100).reshape(10, 10)
cmap = plt.cm.gray
norm = plt.Normalize(data.min(), data.max())
rgba = cmap(norm(data))
# Set the diagonal to red
rgba[range(10), range(10), :3] = 1, 0, 0
fig, ax = plt.subplots()
ax.imshow(rgba, interpolation='nearest')
# Add the colorbar using a ScalarMappable
im = ScalarMappable(norm, cmap)
im.set_array(data)
fig.colorbar(im)
plt.show()
方法2-滥用
设置错误
,设置在上方
,或设置在下方
colormap的
set_bad
、set_over
和set_under
方法允许您标记为NaN或超出colormap指定范围的像素
因此,另一种方法是将这些值设置为NaN,并指定NaN颜色应该是什么(set_bad
。默认情况下,它对大多数颜色贴图是透明的。)
如果您有一个整数数组或已经需要透明的NaN像素,您可以类似地滥用set_over
和set_over
。在这种情况下,您需要在调用imshow
时手动指定vmin
或vmax
作为使用/滥用set_bad
执行此操作的快速示例:
import numpy as np
import matplotlib.pyplot as plt
data = np.arange(100).reshape(10, 10).astype(float)
cmap = plt.cm.gray
cmap.set_bad((1, 0, 0, 1))
# Set the diagonal to NaN
data[range(10), range(10)] = np.nan
plt.imshow(data, cmap=cmap, interpolation='nearest')
plt.show()
与第一种方法相比,这种方法的一个优点是绘制颜色条稍微容易一些。(缺点是这种方法灵活性差得多。):
为了补充Joe非常好的回答,当向
imshow
提供rgba值数组时,鼠标光标读取的z值现在显示rgba值的元组,而不是原始数据
值
为了解决这个问题,我们可以在原始图像上覆盖一个透明图像。
然后,我们可以同时使用此透明图像将颜色条附加到图形上:
import numpy as np
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
data = np.arange(100).reshape(10, 10)
cmap = plt.cm.gray
norm = plt.Normalize(data.min(), data.max())
rgba = cmap(norm(data))
# Set the diagonal to red...
rgba[range(10), range(10), :3] = 1, 0, 0
im = ax.imshow(rgba, interpolation='nearest')
im2 = ax.imshow(data, cmap='gray')
cbar = plt.colorbar(im2, ax=ax)
im2.set_alpha(0.0)
请注意,在这种情况下,在调用im2.set_alpha(0.0)
之前创建颜色条非常重要。
如果不是,颜色栏中的颜色也将是透明的(它们遵循图像的当前alpha)
在不可能遵守创建顺序的情况下,可以使用将颜色栏中颜色的不透明度设置回1
cbar.set_alpha(1.0)
cbar.draw_all()
乔,谢谢你的建议,它们看起来很合理。在这些情况下,这些像素会显示在颜色栏上吗?我不需要它们。在尝试了第一个选项后,我发现颜色条和整个图像的颜色都受到了很大的影响。这可能是因为在渲染到rgb后,值的范围仅下降到(0,1),至少我在颜色栏的标签上看到了这一点,而且我以前有一个更大的范围。因此,图像的某些部分的颜色变得难以区分,尽管如果我在原始数据上调用imshow(),它们明显不同。并且使用
set_bad
,set_下的set_和set_上的不是一个很好的选择,因为我希望能够用不同的颜色标记不同的像素,这就把它们的数量限制在3个。我可能还需要将vmin
和vmax
用于其他目的。默认情况下,添加的颜色不会显示在颜色栏上。然而,为第一种方法制作一个颜色条需要几个额外的步骤,而第二种方法则不需要做任何额外的事情。哦,如果我按照你对第一种方法的建议进行标准化,那么我会得到一个蓝色的方块,而不是我的图像,没有它看起来更像应该的样子。