Matplotlib/Cartopy Mollweide投影经度环绕接缝问题求解
解决xarray+Cartopy绘制contourf时0经度的接缝问题
嘿,这个0经度的接缝问题我之前处理全球NetCDF数据时也碰到过,简直是contourf绘图的“经典坑”!其实核心原因很简单:matplotlib的contourf默认不会把经度的首尾点视为连续的——哪怕0度和360度在地理上是同一个位置,它也会把它们当成两个独立的边界,自然就出现了接缝。
想要把数据当作周期性数据处理,实现首尾点的“无缝衔接”,有几种内联的处理方式,我给你分享两个最实用的:
方法一:扩展数据集,添加360度的重复点
这个思路是手动给数据集补上一个360度的经度点,值和0度点完全一致,让经度维度形成一个闭合的环:
import xarray as xr import matplotlib.pyplot as plt import cartopy.crs as ccrs # 假设你的数据集为ds,经度变量是lon,要绘图的变量是temp(替换成你的变量名) # 1. 复制0度经度的数据,将其经度设为360度 extra_lon = xr.DataArray([360.0], dims="lon") extra_data = ds.temp.isel(lon=0).assign_coords(lon=extra_lon) # 2. 将这个额外的点合并到原数据集 ds_extended = xr.concat([ds, extra_data], dim="lon") # 3. 绘图验证 fig, ax = plt.subplots(subplot_kw={"projection": ccrs.PlateCarree()}) ds_extended.temp.plot.contourf( ax=ax, transform=ccrs.PlateCarree(), levels=20, cmap="viridis" ) ax.coastlines() plt.show()
这样处理后,contourf会把360度的点和0度的点视为连续的,接缝自然就消失了。
方法二:用xarray的pad函数实现循环填充
如果你觉得手动拼接太麻烦,可以用xarray的pad函数,直接在经度维度的末尾循环填充第一个点的数据,再调整经度坐标:
# 1. 对数据进行循环填充,在经度末尾加一个点 ds_padded = ds.pad(lon=(0, 1), mode="wrap") # 2. 调整经度坐标,把最后一个点设为360度 new_lons = xr.concat([ds.lon, xr.DataArray([ds.lon[0] + 360], dims="lon")], dim="lon") ds_padded = ds_padded.assign_coords(lon=new_lons) # 3. 绘图 fig, ax = plt.subplots(subplot_kw={"projection": ccrs.PlateCarree()}) ds_padded.temp.plot.contourf(ax=ax, transform=ccrs.PlateCarree(), levels=20) ax.coastlines() plt.show()
mode="wrap"参数会自动把第一个元素复制到末尾,省去了手动复制数据的步骤,非常方便。
额外提示
如果你的经度范围是-180到180,也可以先把经度转换为0到360的范围,再用上面的方法处理——转换方法也很简单:
ds["lon"] = xr.where(ds.lon < 0, ds.lon + 360, ds.lon) ds = ds.sortby("lon")
这样处理后,首尾点就变成0和360度,再添加360度的重复点就能解决接缝问题啦!
内容的提问来源于stack exchange,提问作者Rutherford Hayes
相关产品推荐
相关产品推荐

