确保 0 在 RdBu 颜色条中变为白色

问题描述 投票:0回答:2

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

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?

matplotlib colorbar colormap
2个回答
13
投票

使用

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()


2
投票

之前的一篇 SO 文章(更改 matplotlib 中的颜色条渐变)想要一个针对更复杂情况的解决方案,但其中一个答案谈到了 matplotlib 文档中的 MidpointNormalize 子类。这样,解决方案就变成了:

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 指出了答案。

© www.soinside.com 2019 - 2024. All rights reserved.