Seaborn 混淆矩阵(热图)2 种配色方案(正确的对角线 vs 错误的休息)
Seaborn Confusion Matrix (heatmap) 2 color schemes (correct diagonal vs wrong rest)
背景
在混淆矩阵中,对角线表示预测标签与正确标签匹配的情况。所以对角线是好的,而所有其他单元格都是坏的。为了向非专家阐明 CM 中的优点和缺点,我想给对角线赋予与其余部分不同的颜色。我想用 Python & Seaborn.
来实现
基本上我正在努力实现这个问题在 R 中的作用 ()
带热图的普通 Seaborn 混淆矩阵
import numpy as np
import seaborn as sns
cf_matrix = np.array([[50, 2, 38],
[7, 43, 32],
[9, 4, 76]])
sns.heatmap(cf_matrix, annot=True, cmap='Blues') # cmap='OrRd'
生成此图像的结果:
目标
我想给非对角线的单元格上色,例如cmap='OrRd'
。所以我想会有 2 个颜色条,1 个蓝色用于对角线,1 个用于其他单元格。最好两个颜色条的值都匹配(例如 0-70 而不是 0-70 和 0-40)。
我将如何处理这个问题?
以下不是用代码做的,是用修图软件做的:
您可以在调用 heatmap()
时使用 mask=
选择要显示的单元格。对角线和 [=26=] 单元格使用两个不同的掩码,您可以获得所需的输出:
import numpy as np
import seaborn as sns
cf_matrix = np.array([[50, 2, 38],
[7, 43, 32],
[9, 4, 76]])
vmin = np.min(cf_matrix)
vmax = np.max(cf_matrix)
off_diag_mask = np.eye(*cf_matrix.shape, dtype=bool)
fig = plt.figure()
sns.heatmap(cf_matrix, annot=True, mask=~off_diag_mask, cmap='Blues', vmin=vmin, vmax=vmax)
sns.heatmap(cf_matrix, annot=True, mask=off_diag_mask, cmap='OrRd', vmin=vmin, vmax=vmax, cbar_kws=dict(ticks=[]))
如果你想花哨一点,可以使用 GridSpec 创建轴以获得更好的布局:
将 numpy 导入为 np
将 seaborn 导入为 sns
fig = plt.figure()
gs0 = matplotlib.gridspec.GridSpec(1,2, width_ratios=[20,2], hspace=0.05)
gs00 = matplotlib.gridspec.GridSpecFromSubplotSpec(1,2, subplot_spec=gs0[1], hspace=0)
ax = fig.add_subplot(gs0[0])
cax1 = fig.add_subplot(gs00[0])
cax2 = fig.add_subplot(gs00[1])
sns.heatmap(cf_matrix, annot=True, mask=~off_diag_mask, cmap='Blues', vmin=vmin, vmax=vmax, ax=ax, cbar_ax=cax2)
sns.heatmap(cf_matrix, annot=True, mask=off_diag_mask, cmap='OrRd', vmin=vmin, vmax=vmax, ax=ax, cbar_ax=cax1, cbar_kws=dict(ticks=[]))
您可以先用颜色图 'OrRd' 绘制热图,然后用颜色图 'Blues' 的热图覆盖它,将上下三角值替换为 NaN,请参见以下示例:
def diagonal_heatmap(m):
vmin = np.min(m)
vmax = np.max(m)
sns.heatmap(cf_matrix, annot=True, cmap='OrRd', vmin=vmin, vmax=vmax)
diag_nan = np.full_like(m, np.nan, dtype=float)
np.fill_diagonal(diag_nan, np.diag(m))
sns.heatmap(diag_nan, annot=True, cmap='Blues', vmin=vmin, vmax=vmax, cbar_kws={'ticks':[]})
cf_matrix = np.array([[50, 2, 38],
[7, 43, 32],
[9, 4, 76]])
diagonal_heatmap(cf_matrix)
在相关问题中,有人询问如何显示颜色条范围不包括对角线(全为 1)的相关数据框。
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
iris = sns.load_dataset('iris').drop(columns=['species'])
corr_df = iris.corr()
plt.figure(figsize=(7,5))
ax = sns.heatmap(corr_df, annot=True, cmap='OrRd', mask=np.eye(len(corr_df)))
ax.set_yticklabels(ax.get_yticklabels(), va='center')
ax.patch.set_facecolor('skyblue')
ax.patch.set_edgecolor('white')
ax.patch.set_hatch('xx')
plt.tight_layout()
plt.show()
背景
在混淆矩阵中,对角线表示预测标签与正确标签匹配的情况。所以对角线是好的,而所有其他单元格都是坏的。为了向非专家阐明 CM 中的优点和缺点,我想给对角线赋予与其余部分不同的颜色。我想用 Python & Seaborn.
来实现基本上我正在努力实现这个问题在 R 中的作用 (
带热图的普通 Seaborn 混淆矩阵
import numpy as np
import seaborn as sns
cf_matrix = np.array([[50, 2, 38],
[7, 43, 32],
[9, 4, 76]])
sns.heatmap(cf_matrix, annot=True, cmap='Blues') # cmap='OrRd'
生成此图像的结果:
目标
我想给非对角线的单元格上色,例如cmap='OrRd'
。所以我想会有 2 个颜色条,1 个蓝色用于对角线,1 个用于其他单元格。最好两个颜色条的值都匹配(例如 0-70 而不是 0-70 和 0-40)。
我将如何处理这个问题?
以下不是用代码做的,是用修图软件做的:
您可以在调用 heatmap()
时使用 mask=
选择要显示的单元格。对角线和 [=26=] 单元格使用两个不同的掩码,您可以获得所需的输出:
import numpy as np
import seaborn as sns
cf_matrix = np.array([[50, 2, 38],
[7, 43, 32],
[9, 4, 76]])
vmin = np.min(cf_matrix)
vmax = np.max(cf_matrix)
off_diag_mask = np.eye(*cf_matrix.shape, dtype=bool)
fig = plt.figure()
sns.heatmap(cf_matrix, annot=True, mask=~off_diag_mask, cmap='Blues', vmin=vmin, vmax=vmax)
sns.heatmap(cf_matrix, annot=True, mask=off_diag_mask, cmap='OrRd', vmin=vmin, vmax=vmax, cbar_kws=dict(ticks=[]))
如果你想花哨一点,可以使用 GridSpec 创建轴以获得更好的布局:
将 numpy 导入为 np 将 seaborn 导入为 sns
fig = plt.figure()
gs0 = matplotlib.gridspec.GridSpec(1,2, width_ratios=[20,2], hspace=0.05)
gs00 = matplotlib.gridspec.GridSpecFromSubplotSpec(1,2, subplot_spec=gs0[1], hspace=0)
ax = fig.add_subplot(gs0[0])
cax1 = fig.add_subplot(gs00[0])
cax2 = fig.add_subplot(gs00[1])
sns.heatmap(cf_matrix, annot=True, mask=~off_diag_mask, cmap='Blues', vmin=vmin, vmax=vmax, ax=ax, cbar_ax=cax2)
sns.heatmap(cf_matrix, annot=True, mask=off_diag_mask, cmap='OrRd', vmin=vmin, vmax=vmax, ax=ax, cbar_ax=cax1, cbar_kws=dict(ticks=[]))
您可以先用颜色图 'OrRd' 绘制热图,然后用颜色图 'Blues' 的热图覆盖它,将上下三角值替换为 NaN,请参见以下示例:
def diagonal_heatmap(m):
vmin = np.min(m)
vmax = np.max(m)
sns.heatmap(cf_matrix, annot=True, cmap='OrRd', vmin=vmin, vmax=vmax)
diag_nan = np.full_like(m, np.nan, dtype=float)
np.fill_diagonal(diag_nan, np.diag(m))
sns.heatmap(diag_nan, annot=True, cmap='Blues', vmin=vmin, vmax=vmax, cbar_kws={'ticks':[]})
cf_matrix = np.array([[50, 2, 38],
[7, 43, 32],
[9, 4, 76]])
diagonal_heatmap(cf_matrix)
在相关问题中,有人询问如何显示颜色条范围不包括对角线(全为 1)的相关数据框。
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
iris = sns.load_dataset('iris').drop(columns=['species'])
corr_df = iris.corr()
plt.figure(figsize=(7,5))
ax = sns.heatmap(corr_df, annot=True, cmap='OrRd', mask=np.eye(len(corr_df)))
ax.set_yticklabels(ax.get_yticklabels(), va='center')
ax.patch.set_facecolor('skyblue')
ax.patch.set_edgecolor('white')
ax.patch.set_hatch('xx')
plt.tight_layout()
plt.show()