如何设置Seaborn热力图y轴按索引实际数值比例缩放
问题场景
现有如下结构的DataFrame对象df:
In [1]: df Out [1]: two one 1.5 11.22 2.0 15.36 2.5 11.00 3.3 12.50 3.5 14.78 5.0 9.00 6.2 26.14
使用如下代码绘制热力图:
In [2]: plt.figure(figsize=(30, 7)) plt.title('Test') ax = sns.heatmap(data=df, annot=True,) plt.xlabel('Test') ax.invert_yaxis() value = 6 index = np.abs(df.index - value).argmin() ax.axhline(index + .5, ls='--') print(index)
运行后得到的效果如下:
现存问题
默认生成的热力图y轴会按数据行顺序等距排列,无法体现索引的实际数值间隔,比如索引3.5和5.0之间的数值差没有对应留白,不符合数值比例展示的需求。预期效果为y轴按实际索引数值比例缩放,无数据的空缺位置留出对应长度的空白,空缺区域数值填充为0。
实现方案
核心逻辑是先对原DataFrame做重索引,补全索引区间内所有位置的行,空缺值填充0,再基于补全后的DataFrame绘图即可实现按实际数值比例排布y轴的效果。
完整可运行代码如下:
import numpy as np import pandas as pd import seaborn as sns import matplotlib.pyplot as plt # -------------------------- 数据补全(核心步骤) -------------------------- # 设定y轴数值精度,步长越小精度越高,可按需调整 y_step = 0.1 # 生成覆盖原索引最小值到最大值的连续完整索引 full_y_index = np.arange(df.index.min(), df.index.max() + y_step, y_step).round(1) # 重索引,无数据的位置填充0 df_for_plot = df.reindex(full_y_index, fill_value=0) # ------------------------------------------------------------------------ plt.figure(figsize=(30, 7)) plt.title('Test') # 绘制热力图时先关闭默认密集y轴标签,后续自定义刻度 ax = sns.heatmap(data=df_for_plot, annot=True, yticklabels=False) plt.xlabel('Test') ax.invert_yaxis() # 自定义y轴刻度,避免标签过密,这里设置每1个数值单位显示一个标签 tick_interval = 1 tick_pos = np.arange(0, len(full_y_index), tick_interval / y_step) tick_labels = np.arange( np.ceil(df.index.min()), np.floor(df.index.max()) + tick_interval, tick_interval ).astype(int) ax.set_yticks(tick_pos) ax.set_yticklabels(tick_labels) # 绘制目标位置参考线 target_value = 6 line_position = (target_value - full_y_index[0]) / y_step ax.axhline(line_position + 0.5, ls='--', color='red') plt.show()
运行后3.5到5.0的索引区间会自动留出对应比例长度的空白区域,空白区域数值填充为0,y轴间距完全匹配索引的实际数值差。
内容的提问来源于stack exchange,提问作者9Jo
相关产品推荐
相关产品推荐

