使用cartopy的central_longitude参数时ISCCP数据与海岸线投影不一致问题
排查ISCCP数据与Cartopy绘图错位问题
核心原因:经度范围不匹配
Cartopy的地理投影默认适配**[-180°, 180°]的经度范围,而你使用的ISCCP数据是[0°, 360°]**(从1.25°E到358.75°E)。当设置central_longitude时,0-360的经度数据在投影转换时会被错误映射,导致陆地轮廓错位。MERRA-2数据大概率本身是[-180°, 180°]范围,因此可以正常显示。
排查与解决步骤
1. 确认并转换经度范围
首先检查数据的经度值:
print(ds.lon.values)
如果输出是0到360的范围,将其转换为-180到180,并重新排序经度(避免绘图时数据顺序混乱):
import xarray as xr # 转换经度 ds['lon'] = xr.where(ds.lon > 180, ds.lon - 360, ds.lon) # 按经度升序排序 ds = ds.sortby('lon')
2. 修正绘图的投影参数设置
确保绘图时明确区分数据坐标投影和地图显示投影:
- 数据本身是经纬度坐标,因此
transform参数要指定ccrs.PlateCarree()(无central_longitude) - 地图显示投影可以设置
central_longitude,传入subplot的projection参数
完整示例代码:
import cartopy.crs as ccrs import matplotlib.pyplot as plt import xarray as xr # 加载并预处理ISCCP数据 ds = xr.open_dataset('isccp_data.nc') ds['lon'] = xr.where(ds.lon > 180, ds.lon - 360, ds.lon) ds = ds.sortby('lon') # 创建带中心经度的地图投影 map_proj = ccrs.PlateCarree(central_longitude=180) # 示例:居中于180°W # 绘图 fig, ax = plt.subplots(figsize=(10, 6), subplot_kw={'projection': map_proj}) ds['your_variable'].plot.pcolormesh( ax=ax, transform=ccrs.PlateCarree(), # 数据的原始投影 cmap='viridis', extend='both' ) ax.coastlines(linewidth=0.8) ax.gridlines(draw_labels=True) plt.show()
3. 排除库导入顺序干扰
库导入顺序极少导致这类问题,但如果仍有怀疑,可以尝试固定导入顺序(例如先导入cartopy,再导入xarray),测试是否有变化:
import cartopy.crs as ccrs import matplotlib.pyplot as plt import xarray as xr
4. 检查数据坐标元数据
确认经度的元数据没有错误,比如单位是否为degrees_east:
print(ds.lon.attrs)
如果元数据标注错误(例如写成degrees_west),会导致坐标解析错误,需要修正:
ds.lon.attrs['units'] = 'degrees_east'
总结
绝大多数情况下,错位问题源于0-360°经度范围未转换为Cartopy默认的-180-180°范围。完成经度转换并配合正确的投影参数设置后,数据即可与海岸线正确对齐。
内容的提问来源于stack exchange,提问作者Logan
相关产品推荐
相关产品推荐

