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

Matplotlib中如何获取/设置无空白colorbar的正确格式化y轴刻度

Matplotlib colorbar配置异常修复方案

问题表现

  • 调用get_ticks()获取的色条y轴刻度与实际数据范围不符:测试数据最小值为17.15116279,但返回的刻度最小值为15;使用该返回值调用.set_ticks()设置刻度后,色条颜色映射错位,且出现多余空白区域。
  • 若不执行cbar.ax.yaxis.set_ticks(vals)语句,色条显示效果正常,但会触发警告:UserWarning: FixedFormatter should only be used together with FixedLocator。

已验证无效的排查方向

  • 直接传入mtick.PercentFormatter作为colorbar的format参数可规避问题,但无法灵活自定义刻度标签格式。
  • 获取刻度前执行fig.draw_without_rendering(),得到的刻度值仍不符合数据范围,还会导致色条出现第二块空白区域。
  • 问题根因初步分析:默认生成的刻度并非全部落在vmin/vmax定义的视图范围内,首尾刻度可能超出数据区间;手动设置刻度时坐标轴会自动扩展视图范围适配所有传入刻度,刻度超出vmin/vmax就会产生空白。但手动将首尾刻度替换为vmin、vmax,并将首尾刻度标签设为空字符串,显示效果仍未达预期。

问题复现代码

import geopandas as gpd # version 0.11.0
import matplotlib.pyplot as plt # version 3.5.2
import matplotlib.colors as clr
from matplotlib import colorbar
from matplotlib.colors import Normalize # tbv colorbar 
from matplotlib import cm
import matplotlib.ticker as mtick
cmap = clr.LinearSegmentedColormap.from_list('custom blue', ["#fce19c", "#c4ddee"], N=400)

world = gpd.read_file(gpd.datasets.get_path('naturalearth_lowres'))
world = world[(world.pop_est>0) & (world.name!="Antarctica")]
vals = [22.36958444, 29.21348315, 30.74534161, 37.42331288, 20.,
       19.31407942, 26.08695652, 26.36165577, 25.0, 17.79279279,
       17.15116279, 19.60784314]
world = world[:len(vals)]
world['gdp_per_cap'] = vals
fig, ax = plt.subplots(1, 1)
ax = world.plot(column='gdp_per_cap', ax=ax, legend=False, cmap=cmapgeelblauw)
from mpl_toolkits.axes_grid1.axes_divider import make_axes_locatable
divider = make_axes_locatable(ax)
cax = divider.append_axes("right", size="5%", pad=0.1)
vmin = world['gdp_per_cap'].min()
vmax = world['gdp_per_cap'].max()
norm = Normalize(vmin=vmin, vmax=vmax)
n_cmap = cm.ScalarMappable(norm=norm, cmap=cmap)
n_cmap.set_array([])
cbar = fig.colorbar(n_cmap, cax=cax)
print(cax==cbar.ax) # True
vals = cbar.ax.get_yticks()
print(vals)
cbar.ax.yaxis.set_ticks(vals)
cbar.ax.set_yticklabels(['{:,.0%}'.format(x/100) for x in vals]) 
plt.show()

修复方案

问题核心逻辑:直接调用set_yticklabels会强制为坐标轴绑定FixedFormatter,但此时坐标轴使用的不是FixedLocator,因此触发匹配警告;而直接取用默认生成的全量刻度重新设置时,超出vmin/vmax范围的首尾刻度会强制坐标轴扩展视图范围,最终导致色条错位、出现空白。
修复操作步骤:

  1. 获取默认生成的原始刻度后,过滤掉所有落在[vmin, vmax]区间外的刻度值;如果需要展示数据最值对应的刻度,可将vmin、vmax追加到有效刻度列表后排序。
  2. 显式为y轴设置FixedLocator绑定筛选后的有效刻度,保证locator和formatter匹配,从根源消除警告,同时避免超界刻度扩展坐标轴范围。

核心修复代码:

cbar = fig.colorbar(n_cmap, cax=cax)
# 过滤超界的无效刻度
raw_ticks = cbar.ax.get_yticks()
valid_ticks = [t for t in raw_ticks if vmin <= t <= vmax]
# 按需追加最值刻度
# valid_ticks = sorted(valid_ticks + [vmin, vmax])
# 显式设置FixedLocator匹配后续的FixedFormatter
cbar.ax.yaxis.set_major_locator(mtick.FixedLocator(valid_ticks))
# 自定义刻度标签格式,可按需调整格式逻辑
cbar.ax.set_yticklabels(['{:,.0%}'.format(x/100) for x in valid_ticks])

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 09:24:16