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

如何使用matplotlib修改自定义分类色条形状 去除底部三角

问题描述
  • 需求:将数据映射为分类变量整数值,匹配自定义色条,最终得到无多余三角的纯矩形标准色条
  • 旧方案痛点:此前绘制同类图需要额外补充颜色、在levels参数中添加额外整数值,抵消色条底部可见性差的小三角,但本次分类中本身包含取值为整数0的类别,旧方案会导致颜色映射错位
  • 当前实现:基于cartopy绘制静止卫星投影下的云类型分类产品,自定义了分类色板,手动为色条添加分类标签,但默认生成的色条两端存在多余三角,无法满足纯矩形要求
    当前色条带多余三角的绘图效果
    原有实现代码:
ax = plt.axes(projection=ccrs.Geostationary(central_longitude=-75))
ax.set_xlim((-3627271.341, 1404173.822))                                       
ax.set_ylim((1564871.9518, 4600199.7649))   
ax.coastlines(resolution='10m', linewidth=0.5, color='black')
ax.add_feature(cartopy.feature.BORDERS, linewidth=0.5, zorder=0, edgecolor='black')
ax.add_feature(cartopy.feature.LAKES, linewidth=0.5, zorder=0, edgecolor='black')
ax.add_feature(cartopy.feature.STATES, linewidth=0.3, edgecolor='black')

cMap = ListedColormap(['#0aa60f', 'white', 'black', '#f2d0ed', '#c991c1', '#e36212', '#f2aa24', 'yellow', '#dfe09d', '#c9c7c9', '#f207f2', '#1f3ef0', '#1991e0', '#02f6fa', 
                       '#6ae68d', '#5c081f'])
levels = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]

my_data = scn[product]
figr = my_data.plot.imshow(transform=crs, cmap = cMap, levels = levels, add_colorbar=False)

cbar = plt.colorbar(figr)
cbar.ax.get_yaxis().set_ticks([])
for j, lab in enumerate(['clear','probably clear','fog','water', 'supercld water', 'mixed', 'opaque ice', 'cirrus', 'overlapping', 'overshooting', 'unknown', 'dust', 'smoke', 
                         'fire']):
    cbar.ax.text(4.2, (2.2 * j + 1) / 2.325, lab, ha='center', va='center')
    
plt.title('Cloud Type on May 4, 2022 over CONUS')
解决方案

色条两端出现三角的核心原因是matplotlib默认会为超出levels范围的值添加延伸标识,不需要额外添加占位颜色或levels值,通过两个核心调整即可得到纯矩形色条:

  1. 调用plt.colorbar()时传入extend='neither'参数,直接关闭色条上下两端的三角延伸标识
  2. 修正分类图的levels设置逻辑:N个离散分类需要对应N个颜色、N+1个层级边界,将levels设置为-0.5到13.5间隔1的序列,让0-13的整数分类值正好落在每个纯色矩形块的中心,避免颜色错位。
修正后代码
import numpy as np
ax = plt.axes(projection=ccrs.Geostationary(central_longitude=-75))
ax.set_xlim((-3627271.341, 1404173.822))                                       
ax.set_ylim((1564871.9518, 4600199.7649))   
ax.coastlines(resolution='10m', linewidth=0.5, color='black')
ax.add_feature(cartopy.feature.BORDERS, linewidth=0.5, zorder=0, edgecolor='black')
ax.add_feature(cartopy.feature.LAKES, linewidth=0.5, zorder=0, edgecolor='black')
ax.add_feature(cartopy.feature.STATES, linewidth=0.3, edgecolor='black')

# 14个分类对应14个颜色,取原自定义色板前14个即可
cMap = ListedColormap(['#0aa60f', 'white', 'black', '#f2d0ed', '#c991c1', '#e36212', '#f2aa24', 'yellow', '#dfe09d', '#c9c7c9', '#f207f2', '#1f3ef0', '#1991e0', '#02f6fa'])
# 14个分类对应15个边界值,每个整数分类正好匹配一个纯色块
levels = np.linspace(-0.5, 13.5, 15)
cat_labels = ['clear','probably clear','fog','water', 'supercld water', 'mixed', 'opaque ice', 'cirrus', 'overlapping', 'overshooting', 'unknown', 'dust', 'smoke', 'fire']

my_data = scn[product]
figr = my_data.plot.imshow(transform=crs, cmap=cMap, levels=levels, add_colorbar=False)

# extend='neither' 关闭色条两端三角,得到纯矩形色条
cbar = plt.colorbar(figr, extend='neither')
cbar.ax.get_yaxis().set_ticks([])
# 标签直接对齐每个色块中心,不需要手动校准偏移系数
for j, lab in enumerate(cat_labels):
    cbar.ax.text(1.7, j, lab, ha='left', va='center', transform=cbar.ax.get_yaxis_transform())
    
plt.title('Cloud Type on May 4, 2022 over CONUS')

调整后色条为标准矩形样式,取值为0的分类会正确匹配第一个绿色,无颜色错位问题。如果需要调整标签和色条的间距,修改cbar.ax.text()的第一个x参数即可,数值越大标签离色条越远。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 19:42:14