如何在热图中设置中心颜色

How to set center color in heatmap

我想在 seaborn 中绘制热图。我的代码如下:

plt.rcParams['font.size'] = 13
plt.rcParams['font.weight'] = 'bold'
my_dpi=96
fig, ax = plt.subplots(figsize=(800/my_dpi, 600/my_dpi), dpi=my_dpi, facecolor='black')
rdgn = sns.diverging_palette(h_neg=130, h_pos=10, s=99, l=55, sep=3)
sns.heatmap(df, cmap=rdgn, center=0.00, annot=True, fmt ='.2%', linewidths=1.3, linecolor='black', cbar=False, ax=ax)
plt.savefig('./image/image.png', dpi=96, facecolor='black')

结果如下: enter image description here

我希望集合0为白色,值>0为红色,值<0为绿色。但是热图中的中心是无效的。

顺便问下如何设置颜色不对称。因为我数据中的最小值为 -0.34,最大值为 1.31。我想设置 0 为白色,-0.34 为最绿,1.31 为最红。

看起来 seaborn.heatmap 的 vminvmax parameters 可能对您有所帮助:

sns.heatmap(df, cmap=rdgn, annot=True, fmt ='.2%', linewidths=1.3,
            linecolor='black', cbar=False, ax=ax, 
            vmin=-0.34, vmax=1.31)

但是似乎没有办法将 non-divergent 彩色地图的中心也设置为 0,因此如果这是必需的功能,则您不能使用 seaborn.heatmap。你能做的最好的事情就是设置 vmin = -vmax 这至少会使中心变白。

看起来你可能有不同的数据(没有硬性限制),在这种情况下你可以考虑使用 divergent color maps 之一(在这种情况下你需要使用 center=0 而不是vmin/vmax)。

center 需要一些 可以 居中的东西。因此,您需要的不是调色板(颜色列表),而是颜色图。 Seaborn为这种情况提供了as_cmap参数,

sns.diverging_palette(..., as_cmap=True)

或者,您当然可以使用任何其他 matplotlib 颜色图,或指定您的自定义颜色图。

import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

data = np.linspace(-0.34, 1.31, 100).reshape(10,10)

fig, ax = plt.subplots()
rdgn = sns.diverging_palette(h_neg=130, h_pos=10, s=99, l=55, sep=3, as_cmap=True)
sns.heatmap(data, cmap=rdgn, center=0.00, annot=True, fmt ='.0%', 
            linewidths=1.3, linecolor='black', cbar=True, ax=ax)

plt.show()

如果您不想将颜色图居中,而是想移动其中点,则不能使用 center。而是 matplotlib.colors.DivergingNorm.

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import DivergingNorm
import seaborn as sns

data = np.linspace(-0.34, 1.31, 100).reshape(10,10)

fig, ax = plt.subplots()
rdgn = sns.diverging_palette(h_neg=130, h_pos=10, s=99, l=55, sep=3, as_cmap=True)
divnorm = DivergingNorm(vmin=data.min(), vcenter=0, vmax=data.max())
sns.heatmap(data, cmap=rdgn, norm=divnorm, annot=True, fmt ='.0%', 
            linewidths=1.3, linecolor='black', cbar=True, ax=ax)

plt.show()

这里,全色图的绿色部分会被挤压,红色部分会被拉伸。