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

如何实现seaborn的heatmap与kdeplot重叠绘制避免挤压

解决方案:Seaborn Heatmap与Kdeplot图层重叠绘制

核心问题原因

  • Seaborn的heatmap默认将透视后的行、列作为分类坐标轴,坐标轴实际范围是[0, 类别数量],而非原始数据的数值范围,和直接用原始数值绘制的kdeplot坐标体系不匹配
  • heatmap默认自带的右侧色卡会占用画布空间,导致heatmap被挤压到左侧
  • 错误使用twinx创建双轴会进一步放大坐标不匹配的问题

修改后可运行代码

import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable

# 先处理数据中逗号作为小数点的格式问题
for col in ['X', 'Y', 'Z']:
    dataset[col] = dataset[col].str.replace(',', '.').astype(float)

f, ax = plt.subplots(figsize=(11, 9), dpi=300)
plt.tick_params(bottom='on')

# 生成透视表并对行、列排序确保坐标映射正确
X1 = dataset.pivot(index="X", columns="Y", values="Z")
x_labels = X1.columns.sort_values()
y_labels = X1.index.sort_values()
X1 = X1.reindex(index=y_labels, columns=x_labels)

# 绘制heatmap,关闭自带色卡避免挤压画布
sns.heatmap(X1, cmap="Spectral", ax=ax, cbar=False)
ax.invert_yaxis()

# 原始数值坐标转heatmap网格坐标:每个格子的中心在索引+0.5位置
def val_to_grid_pos(val, sorted_val_list):
    return np.argwhere(sorted_val_list == val)[0][0] + 0.5

dataset['grid_x'] = dataset['Y'].apply(lambda x: val_to_grid_pos(x, x_labels))
dataset['grid_y'] = dataset['X'].apply(lambda x: val_to_grid_pos(x, y_labels))

# 同一坐标轴上绘制kde,zorder确保在上层显示
sns.kdeplot(x=dataset['grid_x'], y=dataset['grid_y'], ax=ax, zorder=2, color='white', linewidths=1.5)

# 手动添加色卡,不占用heatmap画布空间
divider = make_axes_locatable(ax)
cax = divider.append_axes("right", size="5%", pad=0.1)
plt.colorbar(ax.collections[0], cax=cax)

ax.axis('tight')
plt.show()

关键修改说明

  • 新增坐标映射逻辑:把原始数据的X/Y数值转换为heatmap网格的中心坐标,确保两个图层坐标完全对齐
  • 关闭heatmap默认色卡,手动新增色卡到右侧独立轴,避免挤压heatmap显示区域
  • 取消twinx双轴设置,两个图层共用同一坐标轴,通过zorder参数控制图层上下顺序
  • 提前对透视表的行、列做排序,避免索引顺序混乱导致坐标映射错位

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 23:45:02