Seaborn绘制混淆矩阵热力图时单元格标注数值未居中如何解决
Seaborn混淆矩阵单元格注释偏移问题解决方案
问题复现
使用如下seaborn代码绘制二分类混淆矩阵时,单元格内的百分比标注未对齐到单元格中心:
u=['Fire','No Fire'] v=['Fire','No Fire'] plt.figure(figsize=(5,5),dpi=500) plt.rcParams["font.family"] = "serif" plt.rcParams["font.serif"] = "Times New Roman" b=sns.heatmap(cmat,fmt='.2%',annot=True,cmap='RdYlGn',linewidths=.5,yticklabels=u,xticklabels=v) b.set_yticklabels(u, size = 10) b.set_xticklabels(v, size = 10) plt.yticks(weight = 'bold') plt.xticks(weight = 'bold') plt.ylabel('Actual',fontsize=18,fontweight='bold') plt.xlabel('Predicted',fontsize=18,fontweight='bold') plt.savefig('conf.png', dpi=500,bbox_inches='tight')
问题原因
该偏移通常由两个原因导致:
- 修改刻度标签样式(字号、粗体)时未显式指定对齐参数,matplotlib默认对齐规则在样式修改后出现位置偏差
- 低版本seaborn与matplotlib存在兼容性问题,高dpi绘制场景下注释文本默认对齐逻辑失效
修复方案
- 优先在热力图初始化和刻度设置时显式指定对齐参数,这是最稳定的修复方式,修改后核心代码如下:
u=['Fire','No Fire'] v=['Fire','No Fire'] plt.figure(figsize=(5,5),dpi=500) plt.rcParams["font.family"] = "serif" plt.rcParams["font.serif"] = "Times New Roman" # 通过annot_kws强制单元格注释水平、垂直居中 b=sns.heatmap(cmat,fmt='.2%',annot=True,cmap='RdYlGn',linewidths=.5, yticklabels=u,xticklabels=v, annot_kws={"ha": "center", "va": "center"}) # 设置刻度标签时显式指定对齐方向 b.set_yticklabels(u, size=10, va="center") b.set_xticklabels(v, size=10, ha="center") plt.yticks(weight="bold") plt.xticks(weight="bold") plt.ylabel('Actual',fontsize=18,fontweight='bold') plt.xlabel('Predicted',fontsize=18,fontweight='bold') plt.savefig('conf.png', dpi=500,bbox_inches='tight')
- 如果上述调整后仍存在偏移,可以升级seaborn和matplotlib到最新稳定版本,修复旧版本的已知兼容问题,升级命令:
pip install --upgrade seaborn matplotlib - 临时快速修复可以手动重设所有注释文本的坐标,强制放到单元格中心,在保存图片前添加如下代码即可:
# 遍历所有单元格注释,强制修正位置到单元格中心 for annot_text in b.texts: pos_x, pos_y = annot_text.get_position() annot_text.set_position((pos_x + 0.5, pos_y + 0.5))
内容的提问来源于stack exchange,提问作者Mohamad Marjani
相关产品推荐
相关产品推荐

