总结常用的几种colorbar设置,可以应对很多气象论文绘图需求,包括:
matplotlib colormaps(https://matplotlib.org/stable/users/explain/colors/colormaps.html)官网:

以某年气温距平为例,对称色标:
import matplotlib.pyplot as pltcmap = plt.cm.RdBu_rnorm = None #使用默认的线性归一化levels = np.arange(-14,14.1,2)
主要绘图函数:
def draw_info(fig,axes,data_sets,X_axis,Y_axis,levels_np,cmap = plt.cm.RdBu_r,norm=None): #X_axis,Y_axis就是lon lat#去掉白线(在世界地图的范围时) from cartopy.util import add_cyclic_point# 遍历数据集for ax, data_var in data_sets:# 对 var 进行 add_cyclic_point 操作 cycle_var, cycle_lon = add_cyclic_point(data_var, coord=X_axis) cycle_LON, cycle_LAT = np.meshgrid(cycle_lon, Y_axis) c_var = ax.contourf(cycle_LON, cycle_LAT, cycle_var, zorder=0, alpha=1, extend='both',levels = levels_np, transform=ccrs.PlateCarree(), cmap=cmap,norm=norm)return c_var,fig,axes
colorbar美化函数:
def draw_colorbar(c_var,levels_np,fig,axes,position_list=[0.2, 0.05, 0.6, 0.04],unit=None): position = fig.add_axes(position_list) cbar = fig.colorbar(c_var,cax=position,orientation='horizontal', drawedges=True, extendrect=True, extendfrac='auto', extend='both', ticks=levels_np)''' drawedges=True # 显示色标分级边界(每个格子之间有线) extendrect=True # 色标两端扩展部分为矩形 extendfrac='auto'# 自动设置色标两端扩展的长度 extend='both' # 两端显示超出范围的扩展 ticks=levels_np # 设置色标刻度 ''' cbar.outline.set_linewidth(0.8) # 设置色标边框线宽度 cbar.ax.tick_params(labelsize=10) #设置色标刻度字体大小 cbar.set_label(unit, fontsize=10) #设置单位return fig,axes
如果要反转色标颜色,就删除原来的“_r”:
cmap = plt.cm.RdBu #红→蓝
想要将原来的对称色标修改为不对称的,就修改norm参数,用TwoSlopeNorm:以一个中心值vcenter为分界点,分别对左右两侧数据做线性映射到colormap。

from matplotlib.colors import TwoSlopeNormnorm = TwoSlopeNorm( vmin=-14, vcenter=0, vmax=6 )levels = np.arange(-14, 6.1, 2)
修改levels参数,把负值和正值间距设置为不相等的。
from matplotlib.colors import TwoSlopeNormnorm = TwoSlopeNorm( vmin=-14, vcenter=0, vmax=4 )neg_levels = np.arange(-14, 0, 2) # 负数间隔 2pos_levels = np.arange(0, 4.1, 1) # 正数间隔 1levels = np.concatenate([neg_levels, pos_levels])
在matplotlib色标的基础上进行修改,得到:
base_cmap = plt.cm.RdBu_r levels = np.arange(-14,14.1,2)# 根据levels生成对应数量的颜色 ncolor = len(levels) - 1 colors = base_cmap(np.linspace(0,1,ncolor))# 找到最接近0的位置 zero_idx = np.argmin(np.abs(levels))# 将0附近设为白色 colors[zero_idx-1:zero_idx+1] = [1,1,1,1] cmap = LinearSegmentedColormap.from_list("RdBu_white", colors, N=ncolor ) norm = None
调用LinearSegmentedColormap类,可以指定几个关键颜色,然后matplotlib会在这些颜色之间做线性渐变,生成完整的色标。
colors = ['#0d4472','#6aa5e5','white','white','#e25858','#6d0e0e']positions = [0,0.2,0.455,0.545,0.8,1.0]cmap = LinearSegmentedColormap.from_list("custom_cmap", list(zip(positions, colors)))norm = Nonelevels = np.arange(-14,14.1,2)
一个好用的调色板网站(https://www.codeeeee.com/color/picker.html)方便选择颜色

调用BoundaryNorm,用不同颜色区分范围。

import numpy as np import matplotlib.pyplot as plt from matplotlib.colors import ListedColormap, BoundaryNorm# ===============================# 1. 自定义颜色与区间# =============================== colors = ['blue', 'green', 'white', 'pink', 'orange'] bounds = [-15, -10, -5, 0, 5, 10] # 区间边界,长度 = len(colors)+1 cmap = ListedColormap(colors) norm = BoundaryNorm(bounds, cmap.N)# ===============================# 2. 模拟数据# =============================== lon = np.linspace(0, 360, 100) lat = np.linspace(-90, 90, 60) lon2, lat2 = np.meshgrid(lon, lat)# 示例数据 base_data = 10 * np.sin(np.deg2rad(lat2)) * np.cos(np.deg2rad(lon2 / 2))# 添加小幅随机扰动,让数据不完全规则 noise = np.random.uniform(-5, 5, size=base_data.shape) data = base_data + noise # 最终数据# ===============================# 3. 绘制 contourf# =============================== fig, ax = plt.subplots(figsize=(10,5)) cf = ax.contourf( lon2, lat2, data, levels=bounds, # 使用 bounds 来定义区间 cmap=cmap, norm=norm, extend='both'# 两端超出范围显示 extend ) ax.set_xlabel("Longitude") ax.set_ylabel("Latitude") ax.set_title("BoundaryNorm Example")# ===============================# 4. 添加 colorbar(带 drawedges, extendrect, extendfrac)# =============================== cbar = fig.colorbar( cf, orientation='horizontal', extend='both', drawedges=True, extendrect=True, extendfrac='auto', boundaries=bounds, ticks=bounds ) cbar.set_label("Value") cbar.ax.tick_params(labelsize=10) plt.show()