繁体   English   中英

更改 plt.imshow() 图像像素的颜色

[英]Changing colours of pixels of plt.imshow() image

我需要用 matplotlib 的 imshow() 绘制一个图像,然后用不同的颜色标记一些像素。 仅更改它们在初始数组中的值将不起作用,因为我需要使用我正在使用的颜色图中不存在的颜色。 所以我最初的意图是在第一个图像上方绘制第二个生成的数组,其中大部分被屏蔽,所需的像素没有被屏蔽,并且有一些值(可能不同的值对不同的坐标使用不同的颜色)。 它与 matplotlib 的交互式查看器配合得很好,但是当保存到文件中时,一切都可能因为这个错误而扭曲,我在同样的情况下报告了这个错误: https : //github.com/matplotlib/matplotlib/issues/3057

还有其他选项可以更改某些像素的颜色吗?

您已经建议了最简单的方法(在顶部叠加另一个图像),但是如果这不是您想要的效果,还有其他选择。


方法#1 - 手动渲染和合成图像


最直接的方法是使用颜色图将数组渲染为 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()

在此处输入图片说明

这种方法的一个缺点是您不能只调用fig.colorbar(im) ,因为您要传入预渲染的 rgb 图像。 因此,如果您需要颜色条,则必须使用代理艺术家。 最简单的方法是使用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

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 ScalarMappable是一个抽象基类,通常仅用于继承以支持ScalarMappable 因为我们不需要绘制任何东西,所以我们可以直接使用它。

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 - 滥用set_badset_overset_under


颜色图的set_badset_overset_under方法允许您标记 NaN 或超出颜色图指定范围的像素。

因此,另一种方法是将这些值设置为 NaN 并指定 NaN 颜色应该是什么( set_bad .. 默认情况下,对于大多数颜色图来说它是透明的。)。

如果您有一个整数数组或已经需要透明 NaN 像素,您可以类似地滥用set_overset_under 在这种情况下,您需要在调用imshow时手动指定vminvmax

作为使用/滥用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()

在此处输入图片说明

与第一种方法相比,此方法的一个优点是绘制颜色条更容易一些。 (缺点是这种方法不太灵活。):

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.colorbar()
plt.show()

在此处输入图片说明

添加到 Joe 的非常好的答案中,当向imshow提供一组 rgba 值时,鼠标光标读出的 z 值现在显示 rgba 值的元组,而不是原始data值。

为了解决这个问题,我们可以在原始图像上叠加一张透明图像。 然后我们可以同时使用此透明图像将颜色条附加到图形上:

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)之前创建im2.set_alpha(0.0)很重要。 如果不是,颜色栏中的颜色也将是透明的(它们遵循图像的当前 alpha)。

在无法遵守创建顺序的情况下,可以使用将颜色栏中颜色的不透明度设置回 1

cbar.set_alpha(1.0)
cbar.draw_all()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM