Streamplot色标(colorbar)刻度不匹配问题:成因及修复方法
Matplotlib+Cartopy绘制Streamplot时色标刻度不匹配的原因及修复方案
问题原因
- 颜色映射归一化规则不统一:直接将
streamplot返回的cf3.lines传给colorbar,但streamplot由mag数据驱动颜色时,未显式设置数据的归一化范围,导致色标自动计算的范围与实际数据范围脱节。 - 手动刻度与数据范围不匹配:手动指定
ticks=[0,5,10,15,25,30]时,未同步约束色标的数值范围,若mag的实际极值不在该区间内,就会出现刻度错位。
修复方案
核心思路是让色标与mag数据的归一化规则保持一致,具体步骤:
- 显式创建数据归一化对象,绑定
mag的极值范围 - 使用
ScalarMappable关联归一化对象与颜色映射,将其传给colorbar,而非直接使用cf3.lines - 手动设置刻度时,确保刻度值落在
mag的实际数据范围内
修改后的完整代码
import matplotlib.pyplot as plt from matplotlib.colors import Normalize from matplotlib.cm import ScalarMappable import cartopy.crs as ccrs from mpl_toolkits.axes_grid1.inset_locator import inset_axes # 数据准备部分(u、v、mag、index等) # ... fig = plt.figure() ax = plt.axes(projection=ccrs.PlateCarree()) # 基于mag的实际极值创建归一化对象 norm = Normalize(vmin=mag.min(), vmax=mag.max()) # 绘制流线图时指定归一化规则 cf3 = ax.streamplot(u.longitude, u.latitude, u.isel(valid_time=index).data, v.isel(valid_time=index).data, linewidth=0.5, cmap=plt.cm.jet, arrowsize=1.5, density=5, color=mag, norm=norm, transform=ccrs.PlateCarree()) axins = inset_axes(ax, width="95%", height="2%", loc='lower center', borderpad=-3.6) # 创建关联归一化规则的ScalarMappable对象 sm = ScalarMappable(norm=norm, cmap=plt.cm.jet) sm.set_array(mag) # 基于ScalarMappable生成匹配的色标 bar = fig.colorbar(sm, cax=axins, orientation='horizontal', extendrect=True, label='Velocidade [m/s]') bar.set_ticks(ticks=[0,5,10,15,25,30]) plt.show()
异常效果说明
示例1:色标刻度与流场颜色对应错位,低流速区域的颜色对应色标上的高刻度值,无法准确反映流速大小
示例2:色标刻度分布混乱,部分刻度超出色条的显示范围,导致色标失去参考意义
内容的提问来源于stack exchange,提问作者jose paulo Oliveira
相关产品推荐
相关产品推荐

