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

求助:将Cartopy代码从Orthographic投影改为Robinson投影时出现ValueError的原因及解决方法

Robinson投影报错的原因分析与修复方案

我来帮你拆解这个问题,你遇到的错误本质是投影类型对数据格式的要求差异导致的,咱们一步步来理清楚:

错误原因

你看到的ValueError核心信息是:Robinson投影下,使用shading='nearest'时要求输入的数据是二维规则网格(形状类似(200,360)这样的二维数组),但你的dia_depth_smooth数据是一维的(形状(263,)),完全不匹配网格渲染的要求。

为什么Orthographic投影能正常运行?因为正射投影是局部视角的投影,它对数据的兼容性更强,即使是一维散点数据,也能通过shading参数做简单处理;而Robinson是全局投影,底层渲染逻辑强制要求数据必须是二维网格结构,否则无法完成全局投影的坐标转换和着色计算。

可行解决方案

根据你的数据类型,分两种情况处理:

情况1:你的数据是不规则散点(非规则网格)

如果dia_depth_smooth是零散的经纬度点数据,需要先把它插值到规则网格上,再用Robinson投影绘制:

from matplotlib.ticker import AutoMinorLocator
from scipy.interpolate import griddata
import numpy as np

# 1. 提取原始散点数据
lon = dia_depth_smooth['geolon_t'].values
lat = dia_depth_smooth['geolat_t'].values
depth = dia_depth_smooth.values  # 替换成你的深度列名称,比如dia_depth_smooth['depth'].values

# 2. 创建规则网格(可根据数据范围调整网格密度)
grid_lon = np.linspace(lon.min(), lon.max(), 360)
grid_lat = np.linspace(lat.min(), lat.max(), 200)
grid_lon, grid_lat = np.meshgrid(grid_lon, grid_lat)

# 3. 用最近邻插值将散点转换为网格数据
grid_depth = griddata((lon, lat), depth, (grid_lon, grid_lat), method='nearest')

# 4. 绘制Robinson投影地图
fig, (ax) = plt.subplots(nrows=1, ncols=1, figsize=fig_size_single_golden, constrained_layout=True, subplot_kw=dict(projection=ccrs.Robinson(central_longitude=-118.0)) )

# 改用pcolormesh绘制网格数据
cb = ax.pcolormesh(grid_lon, grid_lat, grid_depth,
                   robust=True, cmap=cm.cm.deep, vmin=0, vmax=2500,
                   transform=ccrs.PlateCarree(), shading='nearest')

# 后续的colorbar和地图装饰代码保持不变
cb.colorbar.ax.yaxis.set_minor_locator(AutoMinorLocator())
ax.coastlines(linewidth=0.5)
ax.add_feature(cartopy.feature.LAND, zorder=1, facecolor='gray', edgecolor='black', linewidth=0.5)
ax.set_title('')
plt.savefig('Figure1b.png', format='png', dpi=600, bbox_inches="tight", pad_inches=0)

情况2:你的数据本来是规则网格,但被展平成了一维

如果dia_depth_smooth是从二维网格展平来的(比如原始是201×361的网格),只需要把数据reshape回二维即可:

from matplotlib.ticker import AutoMinorLocator
import numpy as np

# 1. 将一维数据reshape为二维网格
depth_2d = dia_depth_smooth.values.reshape(201, 361)  # 替换成你原始网格的维度

# 2. 生成对应的二维经纬度网格
lon_1d = dia_depth_smooth['geolon_t'].unique()
lat_1d = dia_depth_smooth['geolat_t'].unique()
lon_2d, lat_2d = np.meshgrid(lon_1d, lat_1d)

# 3. 绘制Robinson投影地图
fig, (ax) = plt.subplots(nrows=1, ncols=1, figsize=fig_size_single_golden, constrained_layout=True, subplot_kw=dict(projection=ccrs.Robinson(central_longitude=-118.0)) )

cb = ax.pcolormesh(lon_2d, lat_2d, depth_2d,
                   robust=True, cmap=cm.cm.deep, vmin=0, vmax=2500,
                   transform=ccrs.PlateCarree(), shading='nearest')

# 后续代码保持不变
cb.colorbar.ax.yaxis.set_minor_locator(AutoMinorLocator())
ax.coastlines(linewidth=0.5)
ax.add_feature(cartopy.feature.LAND, zorder=1, facecolor='gray', edgecolor='black', linewidth=0.5)
ax.set_title('')
plt.savefig('Figure1b.png', format='png', dpi=600, bbox_inches="tight", pad_inches=0)

备选方案:直接绘制散点图(无需插值)

如果不需要网格渲染效果,也可以改用scatter函数直接绘制散点,这样Robinson投影也能正常运行:

from matplotlib.ticker import AutoMinorLocator

fig, (ax) = plt.subplots(nrows=1, ncols=1, figsize=fig_size_single_golden, constrained_layout=True, subplot_kw=dict(projection=ccrs.Robinson(central_longitude=-118.0)) )

# 改用scatter绘制散点
sc = ax.scatter(dia_depth_smooth['geolon_t'], dia_depth_smooth['geolat_t'],
                c=dia_depth_smooth.values,
                cmap=cm.cm.deep, vmin=0, vmax=2500,
                transform=ccrs.PlateCarree())

# 调整colorbar的创建方式
cb = fig.colorbar(sc, shrink=0.8, aspect=40, pad=0.04, orientation="horizontal", label="Diapause Depth (metres)")
cb.ax.yaxis.set_minor_locator(AutoMinorLocator())

ax.coastlines(linewidth=0.5)
ax.add_feature(cartopy.feature.LAND, zorder=1, facecolor='gray', edgecolor='black', linewidth=0.5)
ax.set_title('')
plt.savefig('Figure1b.png', format='png', dpi=600, bbox_inches="tight", pad_inches=0)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 10:37:28