You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Seaborn子图热图中实现共享轴与单一颜色条

问题描述

我希望在单个绘图中绘制多个混淆矩阵,并设置共享x轴、y轴,且仅显示一个颜色条。以下是我目前尝试的代码:

混淆矩阵计算代码

#Calculate the confusion matrices
predicted_mod1 = df_binary["Model1"]
actual_class = df_binary["Observed"]

out_df_mod1 = pd.DataFrame(np.vstack([predicted_mod1, actual_class]).T,columns=['predicted_class','actual_class'])
CF_mod1 = pd.crosstab(out_df_mod1['actual_class'], out_df_mod1['predicted_class'], rownames=['Actual'], colnames=['Predicted'])

predicted_mod2 = df_binary["Model2"]

out_df_mod2 = pd.DataFrame(np.vstack([predicted_mod2, actual_class]).T,columns=['predicted_class','actual_class'])
CF_mod2 = pd.crosstab(out_df_mod2['actual_class'], out_df_mod2['predicted_class'], rownames=['Actual'], colnames=['Predicted'])

predicted_mod4 = df_binary["Model4"]

out_df_mod4 = pd.DataFrame(np.vstack([predicted_mod4, actual_class]).T,columns=['predicted_class','actual_class'])
CF_mod4 = pd.crosstab(out_df_mod4['actual_class'], out_df_mod4['predicted_class'], rownames=['Actual'], colnames=['Predicted'])

predicted_mod5 = df_binary["Model5"]

out_df_mod5 = pd.DataFrame(np.vstack([predicted_mod5, actual_class]).T,columns=['predicted_class','actual_class'])
CF_mod5 = pd.crosstab(out_df_mod5['actual_class'], out_df_mod5['predicted_class'], rownames=['Actual'], colnames=['Predicted'])

predicted_mod6 = df_binary["Model6"]

out_df_mod6 = pd.DataFrame(np.vstack([predicted_mod6, actual_class]).T,columns=['predicted_class','actual_class'])
CF_mod6 = pd.crosstab(out_df_mod6['actual_class'], out_df_mod6['predicted_class'], rownames=['Actual'], colnames=['Predicted'])

绘图代码

fig = plt.figure(figsize=(6, 3), dpi=300)
fig.subplots_adjust(hspace=0.8, wspace=0.6)

ax = fig.add_subplot(2, 3, 1)
sns.heatmap(CF_mod1, cmap='Blues', annot=True, fmt='d')

ax = fig.add_subplot(2, 3, 2)
sns.heatmap(CF_mod2, cmap='Blues', annot=True, fmt='d')

ax = fig.add_subplot(2, 3, 3)
sns.heatmap(CF_mod3, cmap='Blues', annot=True, fmt='d')

ax = fig.add_subplot(2, 3, 4)
sns.heatmap(CF_mod4, cmap='Blues', annot=True, fmt='d')

ax = fig.add_subplot(2, 3, 5)
sns.heatmap(CF_mod5, cmap='Blues', annot=True, fmt='d')

ax = fig.add_subplot(2, 3, 6)
sns.heatmap(CF_mod6, cmap='Blues', annot=True, fmt='d')

plt.show()

当前绘制效果存在每个子图都有色条、轴未共享的问题,期望实现共享x/y轴且仅显示一个颜色条。

数据集

Model1,Model2,Model3,Model4,Model5,Model6,Observed
Yes,Yes,Yes,Yes,Yes,Yes,Yes
Yes,Yes,Yes,Yes,Yes,Yes,Yes
Yes,Yes,Yes,Yes,Yes,Yes,Yes
Yes,Yes,Yes,Yes,Yes,Yes,Yes
Yes,Yes,Yes,Yes,Yes,Yes,Yes
Yes,Yes,Yes,Yes,Yes,Yes,Yes
Yes,Yes,Yes,Yes,Yes,Yes,Yes
Yes,Yes,Yes,Yes,Yes,Yes,Yes
Yes,Yes,Yes,Yes,Yes,Yes,Yes
Yes,Yes,Yes,Yes,Yes,Yes,Yes
Yes,Yes,Yes,Yes,Yes,Yes,Yes
Yes,Yes,Yes,Yes,Yes,Yes,Yes
Yes,Yes,Yes,Yes,Yes,Yes,Yes
Yes,Yes,Yes,Yes,Yes,Yes,Yes
No,No,No,No,No,No,Yes
Yes,Yes,Yes,Yes,Yes,Yes,Yes
Yes,Yes,No,Yes,No,Yes,Yes
No,Yes,No,No,No,Yes,Yes
Yes,Yes,Yes,Yes,Yes,Yes,Yes
Yes,Yes,Yes,Yes,Yes,Yes,Yes
Yes,Yes,Yes,Yes,Yes,Yes,Yes
Yes,Yes,Yes,Yes,Yes,Yes,Yes
Yes,Yes,No,No,No,Yes,Yes
Yes,Yes,Yes,Yes,Yes,Yes,Yes
Yes,Yes,Yes,Yes,Yes,Yes,Yes
Yes,Yes,Yes,Yes,Yes,Yes,Yes
Yes,Yes,Yes,Yes,Yes,Yes,Yes
Yes,Yes,Yes,Yes,Yes,Yes,Yes
Yes,Yes,Yes,Yes,Yes,Yes,Yes
Yes,Yes,Yes,Yes,Yes,Yes,Yes
Yes,Yes,Yes,Yes,Yes,Yes,Yes
Yes,Yes,Yes,Yes,Yes,Yes,Yes
Yes,Yes,Yes,Yes,Yes,Yes,Yes
Yes,Yes,Yes,Yes,Yes,Yes,Yes
Yes,Yes,Yes,Yes,Yes,Yes,Yes
Yes,No,Yes,Yes,Yes,No,Yes
Yes,Yes,Yes,Yes,Yes,Yes,Yes
Yes,No,Yes,Yes,Yes,No,Yes
Yes,No,Yes,Yes,Yes,No,Yes
Yes,Yes,Yes,Yes,Yes,Yes,Yes
Yes,Yes,Yes,Yes,Yes,Yes,Yes
Yes,Yes,Yes,Yes,Yes,Yes,Yes
Yes,Yes,Yes,Yes,Yes,Yes,Yes
No,No,No,No,No,No,No
No,No,No,No,No,No,No
No,No,No,No,No,No,No
No,No,No,No,No,No,No
No,No,No,No,No,No,No
No,No,No,No,No,No,No
No,No,No,No,No,No,No
No,No,No,No,No,No,No
No,No,No,No,No,No,No
No,No,No,No,No,No,No
No,No,No,No,No,No,No
No,No,No,No,No,No,No
No,No,No,No,No,No,No
No,No,No,No,No,No,No
No,No,No,No,No,No,No
No,No,No,No,No,No,No
No,No,No,No,No,No,No
No,No,No,No,No,No,No
Yes,Yes,Yes,Yes,Yes,Yes,No
No,No,No,No,No,No,No
No,Yes,No,No,No,Yes,No
No,Yes,No,No,No,Yes,No
Yes,Yes,Yes,Yes,Yes,Yes,No
No,No,No,No,No,No,No
No,No,No,No,No,No,No
No,No,No,No,No,No,No
No,No,No,No,No,No,No
No,No,No,No,No,No,No
No,No,No,No,No,No,No
No,No,Yes,No,Yes,No,No
No,No,No,No,No,No,No
No,No,No,No,No,No,No
No,No,No,No,No,No,No
No,No,No,No,No,No,No
No,No,No,No,No,No,No
No,No,No,No,No,No,No
No,No,No,No,No,No,No
No,No,No,No,No,No,No
No,No,No,No,No,No,No
No,No,No,No,No,No,No
Yes,Yes,Yes,Yes,Yes,Yes,No
No,No,No,No,No,No,No
No,No,No,No,No,No,No
No,No,No,No,No,No,No
No,No,No,No,No,No,No
No,No,No,No,No,No,No
解决方案

步骤1:简化混淆矩阵计算

用循环批量生成所有模型的混淆矩阵,避免重复代码:

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

# 读取数据(假设已加载到df_binary)
# df_binary = pd.read_csv("your_data.csv")

actual_class = df_binary["Observed"]
model_names = ["Model1", "Model2", "Model3", "Model4", "Model5", "Model6"]
confusion_matrices = []

for model in model_names:
    predicted = df_binary[model]
    out_df = pd.DataFrame(np.vstack([predicted, actual_class]).T, columns=['predicted_class','actual_class'])
    cf = pd.crosstab(out_df['actual_class'], out_df['predicted_class'], rownames=['Actual'], colnames=['Predicted'])
    confusion_matrices.append(cf)

步骤2:实现共享轴与单个颜色条

核心要点:

  • 创建子图时指定sharex=True和sharey=True实现轴共享
  • 统一所有热力图的颜色范围(vmin和vmax),确保色条适配所有子图
  • 仅在指定子图显示色条,或单独创建色条轴

方案1:最后一个子图显示色条

# 创建2行3列的子图,共享x、y轴
fig, axes = plt.subplots(2, 3, figsize=(8, 5), dpi=300, sharex=True, sharey=True)
axes = axes.flatten()  # 将二维轴数组转为一维,方便循环

# 计算所有混淆矩阵的最大、最小值,统一颜色范围
all_values = np.concatenate([cf.values.flatten() for cf in confusion_matrices])
vmin, vmax = all_values.min(), all_values.max()

# 绘制每个热力图,仅最后一个显示色条
for i, (cf, ax, model_name) in enumerate(zip(confusion_matrices, axes, model_names)):
    sns.heatmap(cf, cmap='Blues', annot=True, fmt='d', 
                vmin=vmin, vmax=vmax,
                cbar=(i == len(confusion_matrices)-1),  # 仅最后一个子图显示色条
                ax=ax)
    ax.set_title(model_name)  # 添加模型名称作为子图标题

# 调整子图间距
plt.tight_layout()
plt.show()

方案2:单独放置色条(更美观)

fig, axes = plt.subplots(2, 3, figsize=(9, 5), dpi=300, sharex=True, sharey=True)
axes = axes.flatten()

all_values = np.concatenate([cf.values.flatten() for cf in confusion_matrices])
vmin, vmax = all_values.min(), all_values.max()

# 绘制所有热力图,不显示色条
for i, (cf, ax, model_name) in enumerate(zip(confusion_matrices, axes, model_names)):
    sns.heatmap(cf, cmap='Blues', annot=True, fmt='d', 
                vmin=vmin, vmax=vmax,
                cbar=False,
                ax=ax)
    ax.set_title(model_name)

# 创建色条轴,参数为[左, 下, 宽, 高]
cbar_ax = fig.add_axes([0.92, 0.15, 0.02, 0.7])
fig.colorbar(axes[0].collections[0], cax=cbar_ax)

# 调整布局给色条留空间
plt.tight_layout(rect=[0, 0, 0.9, 1])
plt.show()

内容的提问来源于stack exchange,提问作者UseR10085

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 02:47:02