Matplotlib ListedColormap数组不含最大索引时映射偏移问题
Matplotlib ListedColormap 颜色映射偏移问题解析
问题原因
Matplotlib的plt.imsave默认会对输入数组的值做自动归一化处理:它会把数组中的最小值映射到0,最大值映射到1,再将这个归一化后的值对应到ListedColormap的颜色区间。
你的ListedColormap包含10种颜色,内部是按[0, 1/9, 2/9, ..., 8/9, 1]这10个节点划分颜色映射区间的(n种颜色对应n个节点,相邻节点间的区域映射到对应索引的颜色)。
当数组中没有索引9时,数组最大值是5,所有值会被缩放为
value / 5:- 原索引2 → 2/5=0.4,落在
3/9≈0.333和4/9≈0.444之间 → 映射到索引4的绿色 - 原索引3 → 3/5=0.6,落在
5/9≈0.555和6/9≈0.666之间 → 映射到索引6的橙色 - 原索引5 → 5/5=1 → 映射到索引9的粉色
这就导致了颜色偏移。
- 原索引2 → 2/5=0.4,落在
当数组中包含索引9时,数组最大值是9,所有值被缩放为
value / 9,正好和ListedColormap的节点完全匹配:- 原索引2 → 2/9,对应索引2的节点 → 映射到靛蓝色
- 原索引3 → 3/9,对应索引3的节点 → 映射到蓝色
- 原索引5 →5/9,对应索引5的节点 → 映射到黄色
所以颜色完全正确。
解决方法
调用plt.imsave时,手动指定vmin=0和vmax=9,强制关闭自动归一化,让数组中的索引值直接对应ListedColormap的颜色索引:
plt.imsave('{}/apus.png'.format(outputDir), ar, cmap=cmap, vmin=0, vmax=9)
这样无论数组中是否包含最大索引9,颜色映射都会准确对应你定义的索引关系。
内容的提问来源于stack exchange,提问作者Jeremy Howard
相关产品推荐
相关产品推荐

