I'm just starting with using xarray
for working with n-dimensional NetCDF datasets. I particularly like the techniques for slicing using both indexes and labels (isel
and sel
):
import xarray as xr
ds = xr.open_dataset('/path/to/data.nc', decode_times=False, chunks={'time': 1, 'depth': 1})
v = ds['my-variable'].isel(**{'time': 0, 'depth': 0}).sel(**{'lat': slice(-90,90,10), 'lon': slice(40,-80,5)})
This works great if my longitude slice is increasing (-80° to 40°), but not if I want the 'wrap' version of that, which crosses the antimeridian (40° to -80°), as in my snippet above. For example:
>>> v = ds['my-variable'].isel(**{'time': 0, 'depth': 0}).sel(**{'lat': slice(-90,90,10), 'lon': slice(40,-80,5)})
>>> v['lat'].shape
(0,)
Yet:
>>> v = ds['my-variable'].isel(**{'time': 0, 'depth': 0}).sel(**{'lat': slice(-90,90,10), 'lon': slice(-80,40,5)})
>>> v['lat'].shape
(1501,)
The only difference is 'lon': slice(-80,40,5)
(returns data, but not the data I want) vs 'lon': slice(40,-80,5)
(returns no data).
What is the best way to slice with longitude spanning the antimeridian with xarray
?
Best Answer
Xarray is (intentionally) ignorant of coordinate systems, so it has no special handling for cyclic coordinates such as longitude. Because your longitude array has only increasing values, xarray interprets selections like
slice(40, -80)
in the same way thatx[i:j]
works ifx
is a NumPy array andi > j >= 0
, and thus returns an empty selection.The easiest way to work around this is to use boolean indexing instead:
The inner parentheses are important, because
|
has higher operator precedence than<
in Python.Alternatively (maybe if you're studying the Pacific ocean), you might find it convenient to adjust the coordinate system of your data so it is centered over the anti-meridian instead. This is straightforward to accomplish with
roll
: