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

matplotlib imshow绘制分类栅格时ListedColormap颜色显示错误

问题根因

图例显示正常但栅格渲染颜色和自定义色带不符,核心是ListedColormap搭配imshow的默认映射逻辑不符合离散分类栅格的渲染要求:

  • 默认规则下,imshow会自动把栅格值的最小值、最大值线性拉伸到色带的0到N-1索引区间,中间值按线性插值匹配颜色,不会按照「像素值=色带位置」的逻辑一一对应
  • earthpy.draw_legend是直接根据传入的classes列表按顺序匹配色带颜色生成图例,不受默认拉伸规则影响,因此会出现图例正确、图面错误的错位问题。
    如果分类值不是从0开始的连续整数,这种错位会尤其明显。
修复方案

引入BoundaryNorm手动指定离散值的映射规则,让每个分类值精准匹配预设颜色,修改后的完整代码如下:

## 加载TIF文件
import rioxarray as rxr
import numpy as np
import matplotlib.pyplot as plt
import earthpy.plot as ep
from matplotlib.colors import ListedColormap, BoundaryNorm

data_path = 'folder/test_img.tif'
lctif_1km_20530 = rxr.open_rasterio(data_path, masked=True).squeeze()
lctif_1km_20530 = lctif_1km_20530.astype('int')

### 提取分类值、定义色带与图例名称
classes_20530 = list(np.unique(lctif_1km_20530).astype('int'))
color_list_20530 = ['#FAF5E4', '#006400', '#45C2A5', '#B8AF4F', '#fff3bf', '#0000FF']
class_names_20530 = ['Out of buffer','Forest Formation','Wetlands','Grassland', 'Mosaic Agriculture and Pasture','River, Lake and Ocean']

# 构造自定义色带
cmap_20530 = ListedColormap(color_list_20530)
# 生成分类边界:边界数量比分类数多1,按整数分类值±0.5设置避免浮点匹配误差
bounds = [val - 0.5 for val in classes_20530] + [classes_20530[-1] + 0.5]
# 构造离散归一化器,固定值到颜色的映射关系
norm = BoundaryNorm(bounds, cmap_20530.N)

# 绘图
f, ax = plt.subplots(figsize=(10,5))
# 传入norm参数,禁用默认线性拉伸
im = ax.imshow(lctif_1km_20530, cmap=cmap_20530, norm=norm)
ax.set(title="Landcover classes")
ep.draw_legend(im, titles=class_names_20530, classes=classes_20530)
ax.set_axis_off()
plt.show()
注意事项
  • BoundaryNorm会将落在两个相邻边界区间内的像素值,固定映射到色带对应索引的颜色,不会做线性插值,完全适配土地覆盖这类离散分类栅格的渲染需求
  • 边界值设置为分类值±0.5是针对整数型分类值的通用处理方式,可以避免浮点精度问题导致的像素值匹配错误
  • 后续如果调整分类,只需要同步更新分类值列表、色带列表、图例名称列表即可,边界与归一化器的生成逻辑无需改动

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 22:24:12