Python中创建以0为分界的海陆自定义Colormap技术问询
解决海陆分界Colormap的问题
要实现以0为严格分界(0及以上用陆地配色,0以下用海洋配色),核心是先算出0在数据范围里的位置,再按这个比例分配海洋和陆地的颜色数量,而不是按数据绝对值比例分。具体步骤和代码如下:
关键思路
- 先计算0在
[-12000, 9000]这个数据区间的归一化位置,以此确定海洋色和陆地色各占多少个色阶(总色阶设为256,这是matplotlib常用的色图长度) - 分别提取/生成海洋、陆地的颜色数组,再拼接成完整色图
- 配合
Normalize类确保数据值和色图严格对应,避免分界偏移
修改后的完整代码
import numpy as np import matplotlib.pyplot as plt from matplotlib.colors import ListedColormap, LinearSegmentedColormap, Normalize import matplotlib.cm as cm # 数据范围 vmin = -12000 vmax = 9000 # 计算0对应的归一化位置(在[vmin, vmax]区间的占比) norm_0 = (0 - vmin) / (vmax - vmin) total_colors = 256 # 分配海洋和陆地的颜色数量 ocean_color_num = int(np.round(norm_0 * total_colors)) land_color_num = total_colors - ocean_color_num # 提取海洋色图的颜色(这里用cm.ocean的全范围,也可以调整linspace的区间优化浅海颜色) ocean_cmap = cm.ocean.copy() ocean_colors = ocean_cmap(np.linspace(0, 1, ocean_color_num)) # 创建陆地自定义配色的色图 land_colors_list = ['yellowgreen', 'goldenrod', 'maroon', 'white'] land_nodes = [0.0, 0.05, 0.3, 1.0] land_cmap = LinearSegmentedColormap.from_list('land_cmap', list(zip(land_nodes, land_colors_list))) land_colors = land_cmap(np.linspace(0, 1, land_color_num)) # 拼接海洋和陆地颜色,生成最终色图 final_cmap = ListedColormap(np.concatenate((ocean_colors, land_colors))) # 配套的归一化器,确保数据和色图严格对应 norm = Normalize(vmin=vmin, vmax=vmax) # 测试色图(可选) fig, ax = plt.subplots(figsize=(10, 1)) cb = plt.colorbar(plt.cm.ScalarMappable(norm=norm, cmap=final_cmap), cax=ax, orientation='horizontal') cb.set_label('海拔/深度') plt.show()
说明
- 原来的代码错误地用数据绝对值比例分配色阶,导致0的位置和色图分界不匹配,现在通过
norm_0 = (0 - vmin)/(vmax - vmin)精准计算分界点位置 - 如果你觉得海洋的浅海颜色不够区分,可以调整
ocean_cmap(np.linspace(0.2, 0.9, ocean_color_num))里的linspace区间,过滤掉太浅或太深的颜色 - 配合
Normalize类使用,能保证不管数据怎么缩放,0始终是海陆颜色的分界点
内容的提问来源于stack exchange,提问作者Marcus K.
相关产品推荐
相关产品推荐

