最简且健壮的方法是使用 MaxNLocator(integer=True),它自动选择视觉舒适的整数刻度,适配动态数据范围和图窗缩放,避免手动设 ticks 的越界、坐标错位及不响应重绘等问题。

colorbar 刻度强制为整数的最简方法
直接用 plt.colorbar(..., ticks=range(int(vmin), int(vmax)+1)) 最快,但前提是数据范围不大、且你已知 vmin 和 vmax。更稳妥的做法是让 matplotlib 自动算出合适的整数刻度,避免硬编码。
- 先获取当前 colorbar 的
ax(或通过im.colorbar拿到Colorbar对象) - 调用
cbar.set_ticks(np.arange(int(cbar.vmin), int(cbar.vmax)+1)),但注意:若vmin/vmax是浮点(比如 0.2–4.8),int()会截断,应改用np.floor和np.ceil - 更推荐用
MaxNLocator(integer=True),它能自动适配显示区域宽度,避免刻度挤成一团
用 MaxNLocator(integer=True) 控制 colorbar 刻度
这是最健壮的方式,尤其适合动态数据或不确定范围的图。它不强行塞满所有整数,而是选“视觉上舒服的整数位置”,同时严格保证每个 tick 都是整数。
- 导入:
from matplotlib.ticker import MaxNLocator - 画完 colorbar 后加一句:
cbar.ax.yaxis.set_major_locator(MaxNLocator(integer=True))(竖直 colorbar)或cbar.ax.xaxis.set_major_locator(...)(水平) - 如果想限制最多显示 6 个刻度,传参
MaxNLocator(integer=True, nbins=6) - 注意:该方式对极小范围(如 vmin=1.9, vmax=2.1)可能只显示一个 tick(2),这是正常行为,不是 bug
为什么 set_ticks([...]) 容易出错
手动传整数列表看似直接,但实际常踩三个坑:
- 传入的 list 若超出 colorbar 数据范围(比如
vmin=0.5, vmax=3.2却传[0,1,2,3,4]),matplotlib 会静默忽略越界值,导致顶部/底部无刻度线 - 若数据是 log scale 或自定义 norm,
set_ticks传的仍是数据值,但 colorbar 内部坐标已变换,容易错位 - resize 图窗后,手动设置的 ticks 不会自动重排,而
MaxNLocator会响应
完整可运行示例
import matplotlib.pyplot as plt import numpy as np from matplotlib.ticker import MaxNLocatordata = np.random.randn(10, 10) * 2 + 1.5 # 均值约 1.5,范围大致 -2~5 im = plt.imshow(data, cmap='viridis') cbar = plt.colorbar(im)
关键:强制整数刻度
cbar.ax.yaxis.set_major_locator(MaxNLocator(integer=True))
plt.show()
这行 cbar.ax.yaxis.set_major_locator(...) 是核心,其余都是常规绘图。如果 colorbar 是水平的(orientation='horizontal'),把 yaxis 换成 xaxis 即可。
真正要注意的是:别在 plt.colorbar(..., ticks=[...]) 里硬写死列表,除非你确定数据范围永远不变;动态场景下,MaxNLocator(integer=True) 才是那个“设一次就忘掉”的解法。










