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

Seaborn热力图离散色条异常:不同值显示相同颜色

解决Seaborn热力图离散色条颜色映射错误问题

问题核心是你只定义了离散色板,却没给颜色映射指定对应的数值区间边界,Seaborn默认会把离散色板当成连续渐变色板来用,导致颜色分配和预期不符——比如-5和-4数值接近,被映射到几乎相同的颜色,-3的颜色自然也不对。

修正方案

通过BoundaryNorm明确颜色对应的数值区间,配合调整色板和刻度设置,就能实现正确的离散映射:

import matplotlib as mpl
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd

# 原始数据
plotting_df = pd.DataFrame([[0, 0,  0,  0,  0,  0,  0,  0,  0,  0],
[3, 0,  0,  0,  0,  0,  0,  0,  0,  0],
[0, 0,  0,  0,  0,  0,  0,  0,  0,  0],
[5, 5,  0,  0,  0,  0,  0,  0,  0,  0],
[0, 0,  -4, 0,  0,  0,  0,  0,  0,  0],
[0, 0,  0,  0,  -3, 0,  0,  0,  0,  0],
[0, 0,  3,  0,  0,  0,  0,  0,  0,  0],
[0, 0,  -5, 0,  -5, 0,  0,  0,  0,  0],
[0, 0,  -3, 0,  -3, 0,  0,  -4, 0,  0],
[0, 0,  0,  0,  0,  0,  0,  0,  0,  0]])

# 调整色板:将灰色加入,对应0值(ns)
colors = plt.cm.bwr_r([0, .35, 0.45, .65, .9]).tolist()
colors.insert(3, (.8, .8, .8, 1.0))  # 插入灰色作为第四个颜色
cmap = mpl.colors.ListedColormap(colors)

# 定义数值边界:每个颜色对应的区间,确保覆盖所有数据值
boundaries = [-5.5, -4.5, -3.5, -0.5, 0.5, 2.5, 5.5]
norm = mpl.colors.BoundaryNorm(boundaries, cmap.N)

# 绘制热力图,指定norm参数实现离散映射
fig = plt.figure(figsize=(5.5,4.5))
g = sns.heatmap(plotting_df, cmap=cmap, norm=norm, annot=True, annot_kws={'fontsize':12}, 
                cbar_kws={'aspect':12, 'shrink':.7})

# 设置色条刻度为区间中点,确保标签与颜色对应
cbar = g.collections[0].colorbar
cbar.set_ticks([-5, -4, -3, 0, 3, 5])
cbar.set_ticklabels(['-5', '-4', '-3', 'ns', '3', '5'])

plt.show()

关键修正点

  1. 添加数值边界:boundaries定义了每个颜色对应的数值范围,比如[-5.5, -4.5]对应-5,[-4.5, -3.5]对应-4,确保每个数据值都能匹配到唯一的颜色。
  2. 使用BoundaryNorm:这个类会强制Matplotlib按离散区间分配颜色,彻底替代默认的连续渐变映射逻辑。
  3. 调整色板结构:把灰色直接插入色板对应0值(ns),避免了原来set_under的误用(set_under仅适用于低于vmin的数值,不适合这里的0)。
  4. 对齐刻度与区间:将色条刻度设为每个区间的中点,保证标签和颜色一一对应,不会出现偏移。

这样修改后,-5、-4、-3、0、3、5都会显示各自预期的颜色,解决了同色和颜色不符的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 19:15:58