将 2 个不同的蒙版应用于 seaborn 热图或手动更改单元格的颜色

Min*_*ina 2 mask matplotlib seaborn

我有一个数据框,我想绘制 seaborn 热图:

import seaborn as sns

res = sns.heatmap(df, cmap='flare',xticklabels=1, yticklabels=1,linecolor='white',linewidths=0.5,
                 cbar=True,mask=df.isnull(),cbar_kws={'shrink': 0.6},vmin=vmin, vmax=vmax)
Run Code Online (Sandbox Code Playgroud)

我已经为 NaN 单元应用了掩码。现在,我想通过颜色图中没有的自定义颜色(例如蓝色)更改几个单元格的颜色,以表明这些单元格属于另一个类别。

我的问题是:是否可以将 2 个或更多不同颜色的蒙版应用于 seaborn 热图,或者手动将单元格的颜色更改为完全另一种颜色?

在此输入图像描述

Joh*_*anC 6

目前尚不清楚蓝色方块是如何表示的。以下解决方案假设它们表示为第二个矩阵中的值。第一个热图的绘制与之前一样。然后第二个热图使用特殊的颜色图(在这种情况下使用一种颜色,但也可以是全范围),屏蔽掉所有不应该绘制任何内容的地方。

请注意,掩码可以通过logical or(符号:)进行组合|

from matplotlib import pyplot as plt
from matplotlib.colors import ListedColormap
import seaborn as sns
import pandas as pd
import numpy as np

N = 10
data = np.random.uniform(0, 45, size=(N, N))
for x, y in np.random.randint(0, N, 50).reshape(-1, 2):
    data[x, y] = np.nan  # fill in some nans at random places
df = pd.DataFrame(data)
up_triang = np.triu(np.ones_like(data)).astype(bool)
ax = sns.heatmap(df, cmap='flare', xticklabels=True, yticklabels=True, square=True,
                 linecolor='white', linewidths=0.5,
                 cbar=True, mask=df.isnull() | up_triang, cbar_kws={'shrink': 0.6, 'pad': 0}, vmin=0, vmax=45)

data_special = np.random.randint(0, 5, size=(N, N)) // 4
sns.heatmap(data_special, cmap=ListedColormap(['cornflowerblue']), linecolor='white', linewidths=0.5,
            square=True, cbar=False, mask=(data_special != 1) | up_triang, ax=ax)
ax.plot([0, N, 0, 0], [0, N, N, 0], clip_on=False, color='black', lw=2)
ax.tick_params(left=False, bottom=False)
plt.show()
Run Code Online (Sandbox Code Playgroud)

具有两种配色方案的 Seaborn 热图

当特殊单元格只有一种颜色时,另一种方法是使用颜色图的“下”颜色,并给这些单元格赋予负值。另一个好处是可以在颜色栏中显示颜色。这是一些示例代码:

N = 10
data = np.random.uniform(0, 45, size=(N, N))
for x, y in np.random.randint(0, N, 50).reshape(-1, 2):
    data[x, y] = np.nan
data_special = np.random.randint(0, 5, size=(N, N)) // 4
data[data_special == 1] = -1
df = pd.DataFrame(data)

up_triang = np.triu(np.ones_like(data)).astype(bool)
cmap =  sns.color_palette('mako', as_cmap=True).copy()
cmap.set_under('crimson ')
ax = sns.heatmap(df, cmap=cmap, xticklabels=True, yticklabels=True, square=True,
                 linecolor='white', linewidths=0.5, cbar=True, mask=df.isnull() | up_triang,
                 cbar_kws={'shrink': 0.6, 'pad': 0, 'extend': 'min', 'extendrect': True}, vmin=0, vmax=45)
ax.plot([0, N, 0, 0], [0, N, N, 0], clip_on=False, color='black', lw=2)
ax.tick_params(left=False, bottom=False)
plt.show()
Run Code Online (Sandbox Code Playgroud)

使用底色的热图