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

如何为Cartopy中pcolormesh绘制的土地利用图层添加正确图例

问题根源

你当前代码的图例无法正确对应颜色,是因为pcolormesh绘制分类栅格时,不会自动向坐标轴注册可供图例识别的离散类别句柄。直接传入标签列表调用ax_1.legend()时,matplotlib会自动抓取坐标轴上已有的其他绘图元素(比如你之前添加的湖泊、海岸线、行政边界要素)生成图例,自然和土地利用数据的颜色无法匹配。

可行方案

两种方案都可以实现正确的颜色-类别对应,根据需求选择即可。

方案1:手动构造Patch图例(适配现有代码,改动最小)

这个方案不需要调整你已有的pcolormesh绘图逻辑,只需要提前明确土地利用数据的编码值和标签的对应关系,手动生成匹配对应颜色的图例块即可。
首先导入依赖:

from matplotlib.patches import Patch

将你原代码中pcolormesh和legend的部分替换为以下内容:

# 保存pcolormesh返回的对象,用于提取颜色映射
pcm = ax_1.pcolormesh(cat_land_lons, cat_land_lats, cat_land, 
                      transform=ccrs.PlateCarree(), zorder=3)

# 按你的数据实际编码填写:数组里的值和标签一一对应
# 示例为假设编码0=林地、1=水体、2=荒漠、3=农田、4=城镇,按实际情况调整顺序
landuse_vals = [0, 1, 2, 3, 4]
landuse_labels = ['Forested', 'Water', 'Desert', 'Farmland', 'Urban']

# 提取每个类别对应的实际绘制颜色,生成图例句柄
handles = []
cmap, norm = pcm.cmap, pcm.norm
for val, label in zip(landuse_vals, landuse_labels):
    handles.append(Patch(facecolor=cmap(norm(val)), label=label))

# 传入句柄生成图例,可自行调整位置、字号等参数
ax_1.legend(handles=handles, loc='lower right', fontsize=12, framealpha=1)

关键提醒:landuse_vals的取值和顺序必须和你的cat_land数组内的实际分类编码完全一致,否则会出现颜色和类别错位。

方案2:离散色条式图例(适合分类数量较多的场景)

如果分类数较多,浮动图例框会遮挡地图内容,可以改用带分类标签的色条作为说明,还可以自定义每个类别的配色,更符合土地利用图的常规展示习惯。
首先导入依赖:

import matplotlib.colors as mcolors

对应代码替换为:

# 定义分类映射,可自定义每个类别的显示颜色
landuse_vals = [0, 1, 2, 3, 4]
landuse_labels = ['Forested', 'Water', 'Desert', 'Farmland', 'Urban']
# 示例配色:深绿=林地、蓝色=水体、土黄=荒漠、浅黄=农田、灰色=城镇,可自行调整
landuse_colors = ['#2d6a4f', '#1976d2', '#d8b365', '#f6e8c3', '#737373']

# 构造离散色映射和归一化规则
cmap = mcolors.ListedColormap(landuse_colors)
norm = mcolors.BoundaryNorm(
    [v - 0.5 for v in landuse_vals] + [landuse_vals[-1] + 0.5],
    cmap.N
)

# 绘图时传入自定义配色规则
pcm = ax_1.pcolormesh(cat_land_lons, cat_land_lats, cat_land,
                      transform=ccrs.PlateCarree(), zorder=3,
                      cmap=cmap, norm=norm)

# 添加色条,将刻度替换为分类标签
cbar = fig_1.colorbar(pcm, ax=ax_1, shrink=0.6, pad=0.03, ticks=landuse_vals)
cbar.ax.set_yticklabels(landuse_labels, fontsize=12)
避坑提示
  • 禁止只给legend()传入标签列表、不传入对应句柄,否则matplotlib会随机抓取坐标轴内的其他元素生成图例,必然错位。
  • 如果你的土地利用分类编码不是连续整数(比如存在跳号、非数值编码),必须把所有实际存在的编码值完整列在landuse_vals中,不能按自然顺序臆造。
  • 自定义配色时尽量选择色相差异大的颜色,避免相邻类别颜色相近难以区分。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 15:57:27