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

9
我想在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设为最红。

2个回答

19

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

enter image description here

如果您想将色图的中心点移动而不是居中,那么您不能使用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()

在这里,完整的色图将被压缩在绿色部分并在红色部分被拉伸。

enter image description here


非常感谢。还有一个问题,能让左上角的-34%变得更绿吗? - C.M. Cai
如上所述,您可以使用任何您喜欢的颜色映射。如果没有预定义的matplotlib颜色映射适合您,而且如果您对seaborn选项不满意,您可以定义自己的颜色映射 - ImportanceOfBeingErnest
也许我没有清楚地解释我的问题。因为我的数据的最小值是-0.34,最大值是1.31,它不是对称的。我希望颜色条也是不对称的,现在在-0.34处是浅绿色,在1.31处是深红色。我希望它也可以在-0.34处是深绿色。 - C.M. Cai
好的!谢谢。 - C.M. Cai
5
DivergingNorm已更名为TwoSlopeNorm。详情请参见https://matplotlib.org/stable/api/prev_api_changes/api_changes_3.2.0.html?highlight=divergingnorm#divergingnorm-renamed-to-twoslopenorm - John
显示剩余2条评论

1

看起来 seaborn.heatmap 的 vminvmax 参数 可能会对你有所帮助:

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

然而,似乎没有办法针对非发散色图设置中心为0,因此如果这是必需的功能,则无法使用seaborn.heatmap。你能做的最好的事情就是设置 vmin = -vmax,这样至少可以使中心变为白色。
看起来你可能有发散数据(没有硬性限制),在这种情况下,你可以考虑使用发散色图之一(在这种情况下,你需要使用center=0而不是vmin/vmax)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接