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

matplotlib热图colorbar调整:兼容极小值并展示数值细微差异

问题根源

问题核心是色条的动态范围被离群值抢占,主数据区间的映射分辨率不足。默认使用线性归一化色阶时,1e-9的离群极小值会把色条的动态范围拉得极宽,占比最高的614~620主数值区间仅占色条总长度的不到1%,完全无法展示细微数值差异。

注意:不要直接使用普通LogNorm对数归一化,普通对数刻度下600~620区间的对数值差异极小,依然无法清晰展示数值波动。

默认线性色标渲染效果


方案1:SymLog对称对数归一化(实现最简单)

使用matplotlib内置的SymLogNorm做色阶映射,在指定阈值内使用线性刻度、阈值外使用对数刻度,既完整覆盖1e-9极小值,又能把主数值区间完全展开:

import numpy as np
from numpy import NaN
import matplotlib.pyplot as plt
from matplotlib.colors import SymLogNorm
from mpl_toolkits.axes_grid1 import make_axes_locatable

T = np.array([[6.19314835e+02, 6.19229656e+02, 6.19220233e+02],
              [6.14626547e+02, 6.18217141e+02, 6.19029892e+02],
              [1.00000000e-09,            NaN,            NaN]])

fig, ax = plt.subplots()
# *linthresh是核心参数*:-1~1区间使用对数刻度压缩,大于1的区间使用线性刻度展开
# 显式指定vmin/vmax避免自动归一化出现偏差
im = ax.imshow(
    T,
    norm=SymLogNorm(linthresh=1, vmin=1e-9, vmax=np.nanmax(T))
)

divider = make_axes_locatable(ax)
cax = divider.append_axes("right", size="5%", pad=0.05)
plt.colorbar(im, cax=cax)
plt.show()

效果说明:1e-9到1的区间被对数压缩,仅占色条很小一部分长度,1620的主值区间线性展开,614620之间的数值差异可以清晰分辨。


方案2:自定义分段归一化(读值最直观)

如果觉得对数刻度读值不便,可以用BoundaryNorm自定义色段边界,单独给1e-9极小值分配一个独立色段,剩余所有色条长度都用来展示主数值区间的波动:

import numpy as np
from numpy import NaN
import matplotlib.pyplot as plt
from matplotlib.colors import BoundaryNorm
from mpl_toolkits.axes_grid1 import make_axes_locatable

T = np.array([[6.19314835e+02, 6.19229656e+02, 6.19220233e+02],
              [6.14626547e+02, 6.18217141e+02, 6.19029892e+02],
              [1.00000000e-09,            NaN,            NaN]])

# 自定义色段边界:第一个区间单独留给1e-9极小值,后续按主数值范围细分
bounds = [1e-9, 614, 615, 616, 617, 618, 618.5, 619, 619.5, 620]
cmap = plt.get_cmap('viridis').copy()
norm = BoundaryNorm(bounds, cmap.N)

fig, ax = plt.subplots()
im = ax.imshow(T, cmap=cmap, norm=norm)

divider = make_axes_locatable(ax)
cax = divider.append_axes("right", size="5%", pad=0.05)
# 按自定义边界设置色条刻度,按比例分配色段长度
plt.colorbar(im, cax=cax, ticks=bounds, spacing='proportional')
plt.show()

效果说明:1e-9的异常点单独使用色条最下端的颜色标识,其余色段全部分配给614~620区间,刻度为线性,读值直观,微小数值差异展示最清晰。


补充说明
  • 两种方案都默认自动忽略NaN值,不需要额外对NaN做遮罩处理
  • 可以根据实际数据的波动范围调整linthresh参数或者分段边界的密度,主数值波动越小,主值区间的边界可以设得越密,差异展示效果越好
  • 如果需要突出1e-9的异常点,可以手动修改对应色段的颜色为高对比度色(如红色),和正常数值做区分

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 10:09:45