# xarray slicing across the antimeridian

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`?

• 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. – Richard Law 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 at 12:43

## 1 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 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. – Richard Law Aug 6 '16 at 0:00