确保 0 在 RdBu 颜色条中变白

Making sure 0 gets white in a RdBu colorbar

我使用以下代码片段创建了一个热图:

import numpy as np
import matplotlib.pyplot as plt
d = np.random.normal(.4,2,(10,10))
plt.imshow(d,cmap=plt.cm.RdBu)
plt.colorbar()
plt.show()

结果如下图:

现在,由于数据的中间点不为 0,因此颜色图值为 0 的单元格不是白色,而是有点偏红。

如何强制颜色图使 max=blue、min=red 和 0=white?

A​​ previous SO post () wanted a solution for a more complicated situation, but one of the answers talked about the MidpointNormalize subclass in the matplotlib documentation. 这样,解决方案就变成了:

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

class MidpointNormalize(mpl.colors.Normalize):
    ## class from the mpl docs:
    # https://matplotlib.org/users/colormapnorms.html

    def __init__(self, vmin=None, vmax=None, midpoint=None, clip=False):
        self.midpoint = midpoint
        super().__init__(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))

d = np.random.normal(.4,2,(10,10))
plt.imshow(d,cmap=plt.cm.RdBu,norm=MidpointNormalize(midpoint=0))
plt.colorbar()
plt.show()

感谢 Joe Kington 编写子类,感谢 Rutger Kassies 指出答案。

使用 DivergingNorm.

注:从matplotlib 3.2开始DivergingNorm重命名为TwoSlopeNorm

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

d = np.random.normal(.4,2,(10,10))

norm = mcolors.DivergingNorm(vmin=d.min(), vmax = d.max(), vcenter=0)
plt.imshow(d, cmap=plt.cm.RdBu, norm=norm)

plt.colorbar()
plt.show()