在Matplotlib+Cartopy中实现离散色条的问题排查
自定义Contourf色条问题排查与修复
问题描述
我有一个包含纬度、经度、可用性百分比三列的CSV文件,想要绘制contourf地图,颜色对应规则为:灰色0-90%、蓝色90-95%、绿色95-98%、黄色98-99%、红色99-100%。目前地图可正常绘制,但自定义色条时出现两个问题:
- 90%以上的区域全部显示为绿色,忽略了设定的边界;
- 色条显示范围到105,但数据最大值不超过100。
相关代码如下:
import cartopy.crs as ccrs import cartopy.feature as cf from matplotlib.colors import BoundaryNorm, ListedColormap import matplotlib.pyplot as plt import numpy as np import pandas as pd # Gray 0-90, blue 90-95, green 95-98, yellow 98-99, red 99-100 cmap = ListedColormap(['#bebbbc', '#416ae1', '#7ce494', '#f7f880', '#d77b71']) bounds = [0, 90, 95, 98, 99, 100] norm = BoundaryNorm(bounds, cmap.N) # Reads data in a dataframe containing columns lat, lon and availability (float between 0 and 100) data = pd.read_csv(...) # Create a pivot table to reshape the data into a 2D array availability_2d = data.pivot(index='lat', columns='lon', values='availability') lon_2d, lat_2d = np.meshgrid(availability_2d.columns, availability_2d.index) # Plot the map ax = plt.axes(projection=ccrs.Mercator()) ax.add_feature(cf.COASTLINE) contour = ax.contourf(lon_2d, lat_2d, availability_2d, cmap=cmap, norm=norm, transform=ccrs.PlateCarree()) ax.set_extent([-45, 45, 20, 72]) plt.colorbar(contour) plt.show()
问题原因与修复
问题1:90%以上区域统一显示绿色
contourf默认会自动生成等距色阶,直接忽略传入的norm参数。要让它使用自定义边界,必须显式指定levels参数为你的边界列表。
修改方法:
在contourf调用中添加levels=bounds参数:
contour = ax.contourf(lon_2d, lat_2d, availability_2d, levels=bounds, # 新增此参数 cmap=cmap, norm=norm, transform=ccrs.PlateCarree())
问题2:色条范围显示到105
这是因为colorbar默认会自动扩展范围适配自动生成的色阶。指定levels=bounds后,色条会自动匹配你的边界范围。若仍有异常,可手动强制色条对齐边界:
修改plt.colorbar调用:
plt.colorbar(contour, boundaries=bounds, ticks=bounds)
boundaries确保色条使用自定义区间,ticks让刻度与边界完全对齐,提升可读性。
完整修复后的核心代码片段
# 保持cmap、bounds、norm定义不变... # 调用contourf时指定levels contour = ax.contourf(lon_2d, lat_2d, availability_2d, levels=bounds, cmap=cmap, norm=norm, transform=ccrs.PlateCarree()) # 调整colorbar参数 plt.colorbar(contour, boundaries=bounds, ticks=bounds)
内容的提问来源于stack exchange,提问作者Roman Rdgz
相关产品推荐
相关产品推荐

