具有公平发散颜色图的不对称颜色条

bic*_*sen 4 python matplotlib colorbar

我正在尝试在散点图中绘制不对称的颜色范围。我希望颜色能够使用发散的颜色图来公平地表示强度。我无法更改颜色条来表示这一点。

例如,我想在散点图中绘制范围为 [-2, 10] 的 xy 数据,以便颜色条仅显示范围 -2 到 10,中性色为 0,但“强度”为 -2 和 2是相同的。

我尝试过使用ColorMap Normalization截断 color map,但似乎我需要将两者结合起来,但我无法弄清楚。

MCV 示例

x = np.arange( 0, 1, 1e-1 )
xlen = x.shape[ 0 ]
z = np.random.random( xlen**2 )*12 - 2


splt = plt.scatter( 
    np.repeat( x, xlen ), 
    np.tile( x, xlen ), 
    c = z, cmap = 'seismic',
    s = 400
)

plt.colorbar( splt )
Run Code Online (Sandbox Code Playgroud)

通过使用 MidpointNormalize

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):
        # I'm ignoring masked values and all kinds of edge cases to make a
        # simple example...
        x, y = [self.vmin, self.midpoint, self.vmax], [0, 0.5, 1]
        return np.ma.masked_array(np.interp(value, x, y))
Run Code Online (Sandbox Code Playgroud)
x = np.arange( 0, 1, 1e-1 )
xlen = x.shape[ 0 ]
z = np.random.random( xlen**2 )*12 - 2

norm = MidpointNormalize( midpoint = 0 )

splt = plt.scatter( 
    np.repeat( x, xlen ), 
    np.tile( x, xlen ), 
    c = z, cmap = 'seismic', s = 400,
    norm = norm
)

plt.colorbar( splt )
Run Code Online (Sandbox Code Playgroud)

我可以让颜色条以 0 为中心,但强度不公平。即-2 处的强度比+2 处的强度暗得多。

我在截断颜色图时遇到的问题是我不知道截断它的公平位置在哪里。

以下是我想要在颜色栏中进行的更改的示例: 颜色条更改示例

Asm*_*mus 7

如果我的理解正确,那么当前的问题是,以中点为中心的贴图将颜色从 -2均匀缩放到 0(蓝色),类似地(红色)从 0 缩放到 10。

[self.vmin, self.midpoint, self.vmax] = [-2, 0, 10]您应该在以下[-v_ext, self.midpoint, v_ext] = [-10, 0, 10]位置之间重新缩放,而不是缩放:

v_ext = np.max( [ np.abs(self.vmin), np.abs(self.vmax) ] )  ## = np.max( [ 2, 10 ] )
Run Code Online (Sandbox Code Playgroud)

完整的代码可能如下所示:

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

x = np.arange( 0, 1, 1e-1 )
xlen = x.shape[ 0 ]
z = np.random.random( xlen**2 )*12 - 2

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

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

x = np.arange( 0, 1, 1e-1 )
xlen = x.shape[ 0 ]
z = np.random.random( xlen**2 )*12 - 2

norm = MidpointNormalize( midpoint = 0 )

splt = plt.scatter( 
    np.repeat( x, xlen ), 
    np.tile( x, xlen ), 
    c = z, cmap = 'seismic', s = 400,
    norm = norm
)

plt.colorbar( splt )
plt.show()
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述