首页 > 解决方案 > 为什么我不能使用 cartopy 绘制同一数据集的某些时间平均值?

问题描述

我有一个 3 维 xarray DataArray 的表面温度变化与时间坐标,纬度和经度。我正在使用 Cartopy 可视化数据。您可以在此处找到 125 MB 的文件。

在生成不同时期的时间平均值图时,我发现在包含某些时间步长时无法生成正交投影,例如第 132(索引 131)时间。这是从 0 到 130 的时间平均值图:

正确的温度变化空间图

但是,当我改为执行从 0 到 131 的时间平均值时,就会发生这种情况:

温度变化的空间图不正确

这是我用来生成图的代码:

# import statements

import cartopy.crs as ccrs
import xarray as xr
import numpy as np
import matplotlib.pyplot as plt
from cartopy.util import add_cyclic_point
%matplotlib inline
%config InlineBackend.figure_format = "jpg"

# read in data
ens_mean = xr.open_dataarray('temp_changes_ens_mean.nc')

# time average subset of data
to_plot = ens_mean.isel(time=slice(None,131)).mean(dim='time') # change 130 to 131 to break cartopy

# add cyclic point to avoid white lines
data = to_plot
lon = to_plot.coords['lon']

lon_idx = data.dims.index('lon')
wrap_data, wrap_lon = add_cyclic_point(data.values, coord=lon, axis=lon_idx)


# make an orthographic plot centered on north pole

fig = plt.figure(figsize=(4.5,3.5))
ax = fig.add_subplot(1, 1, 1, projection=ccrs.Orthographic(0, 90))

ax.coastlines()

im = ax.contourf(wrap_lon, to_plot.lat, wrap_data,
                transform=ccrs.PlateCarree())

# add colorbar
cb = fig.colorbar(im,orientation='horizontal',shrink=0.5,pad=0.05)

cb.ax.tick_params(labelsize=8)
cb.set_label('ΔSAT (K)',fontsize=8)

plt.tight_layout(w_pad=0.05)
plt.show()

无论我是否添加循环点,都会发生这种情况。我可以使用 matplotlib 或 xarray 的内置绘图快速绘制数据而不会出错。我已经检查了数据中的 NaN 值。最后,如果我删除轮廓线中的变换参数,它能够产生一个连贯的图,这让我认为是变换步骤产生了这个奇怪的图。

谢谢您的帮助!

标签: pythonmatplotlibpython-xarraycartopy

解决方案


您可以使用ax.set_global()方法来重置坐标限制:

#!/usr/bin/env ipython
# --------------------------------------------
import cartopy.crs as ccrs
import xarray as xr
import numpy as np
import matplotlib.pyplot as plt
from cartopy.util import add_cyclic_point
# --------------------------------------------------------------------------------------
#%matplotlib inline
#%config InlineBackend.figure_format = "jpg"

# read in data
ens_mean = xr.open_dataarray('temp_changes_ens_mean.nc')

# time average subset of data
to_plot = ens_mean.isel(time=slice(None,131)).mean(dim='time') # change 130 to 131 to break cartopy

# add cyclic point to avoid white lines
data = to_plot
lon = to_plot.coords['lon']

lon_idx = data.dims.index('lon')
wrap_data, wrap_lon = add_cyclic_point(data.values, coord=lon, axis=lon_idx)
# ------------------------------------------------------------------
# this is not working:
xlims = (np.min(ens_mean['lon']),np.max(ens_mean['lon'])); 
ylims = (np.min(ens_mean['lat']),np.max(ens_mean['lat']));
# ------------------------------------------------------------------
lon = to_plot.coords['lon']
# ====================================================================================
# make an orthographic plot centered on north pole
# Let us make a working/satisfying plot:

fig = plt.figure(figsize=(4.5,3.5))
ax = fig.add_subplot(1, 1, 1, projection=ccrs.Orthographic(0, 90))

ax.coastlines()

im = ax.contourf(wrap_lon, to_plot.lat, wrap_data,
                transform=ccrs.PlateCarree())

# -----------------------------------------------------------
# add colorbar
cb = fig.colorbar(im,orientation='horizontal',shrink=0.5,pad=0.05)

cb.ax.tick_params(labelsize=8)
cb.set_label('ΔSAT (K)',fontsize=8)

plt.tight_layout(w_pad=0.05)

ax.set_global();
#ax.set_xlim(xlims);
#ax.set_ylim(ylims);

plt.show()

推荐阅读