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

Matplotlib contourf自定义配色时双向拓展colorbar颜色重复问题

使用contourf绘图时设置了自定义配色方案,且将colorbar设置为两端拓展模式,但实际输出中色条两端的最后两个区间颜色相同(如图所示),期望每个区间都能匹配预设的不同颜色。
所用脚本如下:

import matplotlib.pyplot as plt
import matplotlib.colors
import numpy as np
from mpl_toolkits.basemap import Basemap
val=np.random.random((37,97))
theLats=np.arange(0,90.3,2.5)
theLons=np.arange(-50,190.3,2.5)
xx, yy = np.float32(np.meshgrid(theLons, theLats))
m = Basemap(projection='cyl', resolution='l',
            llcrnrlat=5, llcrnrlon=65,
            urcrnrlat=40, urcrnrlon=100)
m.drawcoastlines()
parallels = np.arange(-90.,90,20.)
m.drawparallels(parallels,labels=[1,0,0,0],fontsize=10)
meridians = np.arange(0.,360.,20.)
m.drawmeridians(meridians,labels=[0,0,0,1],fontsize=10)
x, y = m(xx, yy)
colors=['red', 'darkorange', 'goldenrod','gold', 'lightgreen','limegreen','aquamarine','aqua','blue']
cm = matplotlib.colors.ListedColormap(colors)
clevs = np.arange(0.2,.8,0.1)
cs = m.contourf(x,y,val,clevs,cmap=cm,extend='both')
cbar = m.colorbar(cs,location='right',pad="5%")
plt.show()

问题示例图:
示例图


原因分析

  • 你定义的clevs = np.arange(0.2,.8,0.1)共生成6个边界值,对应5个普通数值区间,配合extend='both'参数,总共有<0.2、5个中间区间、>0.7共7个需要配色的区间。
  • 你传入的自定义配色列表有9个颜色,matplotlib默认会自动从给定颜色中均匀采样映射到7个区间,导致相邻区间出现重复颜色,就是你看到的色条两端区间颜色一致的问题。

解决方案

通过BoundaryNorm明确绑定区间和颜色的映射关系,避免matplotlib自动采样取色即可解决问题,以下是两种适用场景的修改方案:

方案1:保留原有等级范围,适配9个自定义颜色

如果不需要调整clevs的数值范围,直接明确颜色映射规则即可:

import matplotlib.pyplot as plt
import matplotlib.colors
import numpy as np
from mpl_toolkits.basemap import Basemap

val=np.random.random((37,97))
theLats=np.arange(0,90.3,2.5)
theLons=np.arange(-50,190.3,2.5)
xx, yy = np.float32(np.meshgrid(theLons, theLats))
m = Basemap(projection='cyl', resolution='l',
            llcrnrlat=5, llcrnrlon=65,
            urcrnrlat=40, urcrnrlon=100)
m.drawcoastlines()
parallels = np.arange(-90.,90,20.)
m.drawparallels(parallels,labels=[1,0,0,0],fontsize=10)
meridians = np.arange(0.,360.,20.)
m.drawmeridians(meridians,labels=[0,0,0,1],fontsize=10)
x, y = m(xx, yy)

colors=['red', 'darkorange', 'goldenrod','gold', 'lightgreen','limegreen','aquamarine','aqua','blue']
clevs = np.arange(0.2,.8,0.1)
# 取列表第一个颜色作为小于0.2的拓展色,最后一个作为大于0.7的拓展色,中间7个取5个对应普通区间
cm = matplotlib.colors.ListedColormap(colors[1:6])
cm.set_under(colors[0])
cm.set_over(colors[-1])
# 明确绑定区间和颜色
norm = matplotlib.colors.BoundaryNorm(clevs, ncolors=cm.N, extend='both')

cs = m.contourf(x,y,val,clevs,cmap=cm,norm=norm,extend='both')
cbar = m.colorbar(cs,location='right',pad="5%")
plt.show()

方案2:调整等级范围,用完9个自定义颜色

如果你希望9个颜色全部对应不同的数值区间,调整clevs的边界数量即可:

# 其他代码和上述一致,仅修改clevs和colormap定义部分
colors=['red', 'darkorange', 'goldenrod','gold', 'lightgreen','limegreen','aquamarine','aqua','blue']
cm = matplotlib.colors.ListedColormap(colors)
# 8个边界对应7个普通区间,加两端拓展共9个区间,刚好匹配9个颜色
clevs = np.arange(0.1, 0.9, 0.1)
norm = matplotlib.colors.BoundaryNorm(clevs, ncolors=cm.N, extend='both')

cs = m.contourf(x,y,val,clevs,cmap=cm,norm=norm,extend='both')
cbar = m.colorbar(cs,location='right',pad="5%")
plt.show()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 19:15:03