简体   繁体   English

如何获取自定义色彩映射(matplotlib / python)中屏蔽值的透明度

[英]How to obtain transparency for masked values in customised colormap (matplotlib/python)

I have come across this useful class MidpointNormalize that allows you to choose a data value to correspond to the midpoint colour of your colour-scale. 我遇到过这个有用的类MidpointNormalize ,它允许您选择一个数据值来对应您的色阶的中点颜色。 Effectively this means you can shift the midpoint colour of your colour bar by properly remapping the interval [0,1] on itself. 实际上,这意味着您可以通过正确地重新映射自身的间隔[0,1]来移动颜色条的中点颜色。 I need to use this class and – at the same time – mask certain data values. 我需要使用这个类,并且 - 同时 - 屏蔽某些数据值。 However, when I mask certain values they do not become transparent as desired, instead they appear over-saturated in colour. 但是,当我屏蔽某些值时,它们不会根据需要变得透明,而是显示颜色过饱和。

So: how can I make the masked data transparent using thie MidpointNormalize class? 那么:如何使用MidpointNormalize类使蒙面数据透明? I post a runnable minimal example 我发布了一个可运行的最小例子

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors as colors
import matplotlib.cm as cm


class MidpointNormalize(colors.Normalize):
    def __init__(self, vmin=None, vmax=None, midpoint=None, clip=False):
        self.midpoint = midpoint
        colors.Normalize.__init__(self, vmin, vmax, clip)

    def __call__(self, value, clip=None):
        x, y = [self.vmin, self.midpoint, self.vmax], [0, 0.5, 1]
        return np.ma.masked_array(np.interp(value, x, y))


N = 100
non_masked_data = np.random.rand(N,N)*4.0-2.0
data = np.ma.masked_where(non_masked_data < -1.0, non_masked_data)

fig, ax = plt.subplots()
ax.set_axis_bgcolor('black')

norm_me = MidpointNormalize(midpoint=1.,vmin=data.min(),vmax=data.max())

plot = plt.imshow(data, origin='lower', interpolation='none', cmap="RdBu_r", norm=norm_me)
cb   = fig.colorbar(plot)
plt.show()

The MidpointNormalize originates from this answer in which there is an explicit comment "I'm ignoring masked values and all kinds of edge cases to make a simple example" . MidpointNormalize源于这个答案 ,其中有一个明确的评论“我忽略了掩盖值和各种边缘情况来做一个简单的例子”

In this case, you do not want to ignore masked values. 在这种情况下,您不希望忽略屏蔽值。 Hence you need to propagate the mask through to the output of the __call__ . 因此,您需要将掩码传播到__call__的输出。

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors as colors

class MidpointNormalize(colors.Normalize):
    def __init__(self, vmin=None, vmax=None, midpoint=None, clip=False):
        self.midpoint = midpoint
        colors.Normalize.__init__(self, vmin, vmax, clip)

    def __call__(self, value, clip=None):
        # Note that I'm ignoring clipping and other edge cases here.
        result, is_scalar = self.process_value(value)
        x, y = [self.vmin, self.midpoint, self.vmax], [0, 0.5, 1]
        return np.ma.array(np.interp(value, x, y), mask=result.mask, copy=False)

N = 100
non_masked_data = np.sort(np.random.rand(N,N)*4.0-2.0)
data = np.ma.masked_where(non_masked_data < -1.0, non_masked_data)

fig, ax = plt.subplots()
ax.set_facecolor('black')

norm_me = MidpointNormalize(midpoint=1.,vmin=data.min(),vmax=data.max())
plot = plt.imshow(data, origin='lower', interpolation='none', cmap="RdBu_r", norm=norm_me)
cb   = fig.colorbar(plot)
plt.show()

I added another note in the class, to warn that I'm ignoring clipping and other edge cases here. 我在课堂上添加了另一个注释,警告我在这里忽略剪辑和其他边缘情况。 ;-) ;-)

The result is the following where masked values are transparent (hence the black background is shown). 结果如下掩码值是透明的(因此显示黑色背景)。

在此输入图像描述

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

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