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

使用inset_axes嵌入Cartopy南极投影地图报错,求解决方案

解决Cartopy嵌入子图投影报错及剖面位置地图嵌入问题

问题描述

已生成多个特定经度的海洋剖面图,希望在每个剖面图子图中嵌入显示该剖面位置的地图,添加嵌入地图代码后出现以下问题:

  • 报错NameError: name 'SouthPolarStereo' is not defined
  • 尝试其他投影时出现KeyError 'geo'

原代码片段:

import matplotlib.pyplot as plt
import matplotlib.path as mpath
import numpy as np
import pandas as pd
import xarray as xr
import cartopy
import cartopy.crs as ccrs

num_plots = len(range(0, 360, 20))
cols = 2  # Number of columns in the subplot grid
rows = (num_plots + cols - 1) // cols  # Calculate the number of rows

fig, axs = plt.subplots(rows, cols, figsize=(20, 40))

for idx, ax, in zip(range(0, 360, 20), axs.flat):
    im = mydataselection.plot(cmap='plasma', vmin=-2, vmax=8, ax=ax)
    ax.invert_yaxis()
    ax.set_title(f"titlestring")
    ax.set_xticks(xtickvalues)
    ax.set_xticklabels(np.round(xticklabelvalues,1))
    ax.set_xlabel('Longitude [°N]')

    axins = ax.inset_axes([0.1, 0.1, 0.2, 0.3], projection=SouthPolarStereo())
    axins.set_extent([-180, 180, -90, -50], ccrs.PlateCarree())
    axins.add_feature(cartopy.feature.LAND, edgecolor='black', facecolor='gray')
    axins.add_feature(cartopy.feature.OCEAN)
    axins.gridlines()

    # Make circular inset map
    circle = PathPatch(Path.circle((0.5, 0.5), radius=0.5), transform=axins.transAxes, facecolor='none',  edgecolor='black')
    axins.add_patch(circle)


# Hide any remaining empty subplots
for ax in axs.flat[num_plots:]:
    ax.axis('off')

plt.tight_layout()
plt.subplots_adjust(top=0.9)
plt.show()

错误原因分析

  1. NameError:SouthPolarStereo是cartopy.crs模块下的类,代码中直接调用SouthPolarStereo()未加导入的模块前缀ccrs.,导致Python找不到该类。
  2. KeyError 'geo':一是路径对象引用错误,导入的是matplotlib.path as mpath,但代码中直接用Path和PathPatch未加mpath.前缀;二是matplotlib的inset_axes默认不自动兼容cartopy投影,需确保参数传递正确。

修正方案及完整代码

关键修正点:

  • 投影类调用改为ccrs.SouthPolarStereo()
  • 路径对象改为mpath.Path和mpath.PathPatch
  • 在嵌入地图中添加当前剖面的经度线,明确标注位置
  • 调整圆形遮罩的创建方式,适配cartopy极地投影

修正后的完整代码:

import matplotlib.pyplot as plt
import matplotlib.path as mpath
import numpy as np
import pandas as pd
import xarray as xr
import cartopy
import cartopy.crs as ccrs

num_plots = len(range(0, 360, 20))
cols = 2  # Number of columns in the subplot grid
rows = (num_plots + cols - 1) // cols  # Calculate the number of rows

fig, axs = plt.subplots(rows, cols, figsize=(20, 40))

for idx, ax in zip(range(0, 360, 20), axs.flat):
    # 绘制海洋剖面图(保留原有逻辑)
    im = mydataselection.plot(cmap='plasma', vmin=-2, vmax=8, ax=ax)
    ax.invert_yaxis()
    ax.set_title(f"Longitude: {idx}°E")
    ax.set_xticks(xtickvalues)
    ax.set_xticklabels(np.round(xticklabelvalues, 1))
    ax.set_xlabel('Latitude [°N]')  # 修正原代码标注错误,沿经度切的剖面横轴应为纬度

    # 创建嵌入地图的子轴,使用正确的cartopy投影
    axins = ax.inset_axes([0.1, 0.1, 0.2, 0.3], projection=ccrs.SouthPolarStereo())
    axins.set_extent([-180, 180, -90, -50], ccrs.PlateCarree())
    
    # 添加地图要素
    axins.add_feature(cartopy.feature.LAND, edgecolor='black', facecolor='gray')
    axins.add_feature(cartopy.feature.OCEAN)
    axins.gridlines(draw_labels=False)

    # 绘制当前剖面的经度线(红色线条标注位置)
    axins.plot([idx, idx], [-90, -50], color='red', linewidth=2, transform=ccrs.PlateCarree())

    # 创建圆形遮罩,适配极地投影边界
    theta = np.linspace(0, 2*np.pi, 100)
    center, radius = [0.5, 0.5], 0.5
    verts = np.vstack([np.sin(theta), np.cos(theta)]).T
    circle_path = mpath.Path(verts * radius + center)
    axins.set_boundary(circle_path, transform=axins.transAxes)

# 隐藏空的子图
for ax in axs.flat[num_plots:]:
    ax.axis('off')

plt.tight_layout()
plt.subplots_adjust(top=0.9)
plt.show()

额外说明

  • 红色线条明确标记当前剖面的经度位置,方便主图与嵌入地图的对应
  • 圆形遮罩改用mpath.Path生成,适配cartopy极地投影的边界显示
  • 修正了原代码中横轴标注的错误,符合海洋经度剖面的常规逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 16:04:52