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


>>> v = ds['my-variable'].isel(**{'time': 0, 'depth': 0}).sel(**{'lat': slice(-90,90,10), 'lon': slice(-80,40,5)})
>>> v['lat'].shape

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?

  • Unlikely to work but do you get anything if you use 'lon': slice(40,280,5) ? – mkennedy Aug 4 '16 at 23:21
  • @mkennedy yes, but only 40°→179.9°, so only up to the antimeridian. – alphabetasoup Aug 4 '16 at 23:24
  • Well, it was a long shot. – mkennedy Aug 4 '16 at 23:25
  • Related question here : to change longitude from 0/360 to -180/180 stackoverflow.com/questions/53345442/… – Florian Apr 5 '19 at 12:43

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 that x[i:j] works if x is a NumPy array and i > j >= 0, and thus returns an empty selection.

The easiest way to work around this is to use boolean indexing instead:

ds.sel(lon=(ds.lon < -80) | (ds.lon > 40))

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:

ds_rolled = ds.assign_coords(lon=(ds.lon % 360)).roll(lon=(ds.dims['lon'] // 2))
  • Thank you. I had got as far as rolling and shifting, but the Boolean indexing works great, and in particular keeps on behaving lazily. – alphabetasoup Aug 6 '16 at 0:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.