如何在Seaborn热力图中用字典为值分配固定颜色并统一图例
固定热力图数值颜色并统一图例的实现方法
要实现「不同热力图中同一数值对应固定颜色、共用统一图例」的需求,你可以通过将颜色字典转换为matplotlib可识别的色图规则,配合边界归一化来实现,具体步骤如下:
1. 准备颜色映射与归一化规则
先把你的颜色字典转换成ListedColormap,同时设置BoundaryNorm来确保每个整数对应独立的颜色区间,避免因缺失值导致颜色偏移:
import seaborn as sns import matplotlib.pyplot as plt from matplotlib.colors import ListedColormap, BoundaryNorm from matplotlib.patches import Patch # 你的颜色映射字典 cmap_dict = {0:'#FFFFFF',1:'#ff2a00', 2:'#ff5500', 3:'#ff8000', 4:'#ffaa00', 5:'#ffd500'} # 按数值顺序提取颜色,生成matplotlib色图对象 sorted_keys = sorted(cmap_dict.keys()) colors = [cmap_dict[key] for key in sorted_keys] cmap = ListedColormap(colors) # 设置边界,让每个整数对应独立的颜色区间(比如0对应[-0.5,0.5],1对应[0.5,1.5]) bounds = [-0.5 + i for i in range(len(sorted_keys)+1)] norm = BoundaryNorm(bounds, cmap.N)
2. 绘制热力图
绘制每个过滤后的DataFrame时,指定cmap、norm,并固定vmin和vmax为0和5,确保颜色映射范围统一:
# 示例:模拟两个过滤后的DataFrame(df1缺少值3,df2缺少值5) import pandas as pd import numpy as np # 生成原始15x15数据 df_original = pd.DataFrame(np.random.randint(0,6, size=(15,15))) # 模拟过滤操作:df1移除值3,df2移除值5 df1 = df_original.replace(3, 0) df2 = df_original.replace(5, 0) # 绘制第一个热力图 plt.figure(figsize=(10,5)) plt.subplot(121) sns.heatmap(df1, square=False, yticklabels=True, xticklabels=False, cmap=cmap, norm=norm, vmin=0, vmax=5, cbar=False, annot=False) plt.title("过滤后缺少值3的热力图") # 绘制第二个热力图 plt.subplot(122) sns.heatmap(df2, square=False, yticklabels=True, xticklabels=False, cmap=cmap, norm=norm, vmin=0, vmax=5, cbar=False, annot=False) plt.title("过滤后缺少值5的热力图")
3. 添加统一图例
手动创建包含所有0-5数值的图例,添加到图中:
# 创建图例元素:每个数值对应颜色块和标签 legend_elements = [Patch(facecolor=cmap_dict[key], label=str(key)) for key in sorted_keys] # 将图例添加到图的指定位置 plt.legend(handles=legend_elements, bbox_to_anchor=(1.2, 1), loc='upper left', title="数值对应颜色") plt.tight_layout() plt.show()
关键说明
BoundaryNorm会把每个整数映射到独立的颜色区间,即使某张热力图没有某个数值,颜色规则依然保持不变。- 固定
vmin=0和vmax=5,确保所有热力图的颜色标尺范围一致,不会因数据分布变化而偏移。 - 手动创建图例可以保证所有热力图共用一套颜色说明,避免每个图单独显示色条的混乱。
内容的提问来源于stack exchange,提问作者Yash
相关产品推荐
相关产品推荐

