pythondatetimematplotlibplotpython-xarray

How to enable season selection as JJAS instead of JJA in xarray


I am relatively new to python and programming and have been trying to make some initial plots of precipitation data for the Indian subcontinent specifically for the indian summer monsoon through the period of June,July,August and September. I have managed to understand some of the code in a tutorial to obtain plot for JJA shown below but failing to modify it suitably to show me season as JJAS instead of JJA. Simply substituting JJAS in place of JJA ofcourse yielded the error

KeyError: 'JJAS'

I have seen one solution to this on the same forum but I am unable to adapt it to my code. I would be extremely grateful if I could receive any advice on this. Thank you !

Below is the code

import xarray as xr
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
import numpy as np
import cmocean

accesscm2_pr_file = r'C:\Users\uSER\Desktop\DissTrack1\ESGF data files\pr_Amon_CAMS-CSM1-0_historical_r1i1p1f1_gn_185001-201412.nc'
dset = xr.open_dataset(accesscm2_pr_file)

clim = dset['pr'].groupby('time.season').mean('time', keep_attrs=True)

clim.data = clim.data * 86400
clim.attrs['units'] = 'mm/day'

fig = plt.figure(figsize=[12,5])
ax = fig.add_subplot(111, projection=ccrs.PlateCarree(central_longitude=180))
clim.sel(season='JJAS').plot.contourf(ax=ax,
                   levels=np.arange(0, 13.5, 1.5),
                   extend='max',
                   transform=ccrs.PlateCarree(),
                   cbar_kwargs={'label': clim.units},
                   cmap=cmocean.cm.haline_r)
ax.coastlines()
plt.show()


---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
~\anaconda3\lib\site-packages\pandas\core\indexes\base.py in get_loc(self, key, method, tolerance)
   3360             try:
-> 3361                 return self._engine.get_loc(casted_key)
   3362             except KeyError as err:

~\anaconda3\lib\site-packages\pandas\_libs\index.pyx in pandas._libs.index.IndexEngine.get_loc()

~\anaconda3\lib\site-packages\pandas\_libs\index.pyx in pandas._libs.index.IndexEngine.get_loc()

pandas\_libs\hashtable_class_helper.pxi in pandas._libs.hashtable.PyObjectHashTable.get_item()

pandas\_libs\hashtable_class_helper.pxi in pandas._libs.hashtable.PyObjectHashTable.get_item()

KeyError: 'JJAS'

The above exception was the direct cause of the following exception:

KeyError                                  Traceback (most recent call last)
~\AppData\Local\Temp/ipykernel_16124/3658430410.py in <module>
     15 fig = plt.figure(figsize=[12,5])
     16 ax = fig.add_subplot(111, projection=ccrs.PlateCarree(central_longitude=180))
---> 17 clim.sel(season='JJAS').plot.contourf(ax=ax,
     18                    levels=np.arange(0, 13.5, 1.5),
     19                    extend='max',

~\anaconda3\lib\site-packages\xarray\core\dataarray.py in sel(self, indexers, method, tolerance, drop, **indexers_kwargs)
   1269         Dimensions without coordinates: points
   1270         """
-> 1271         ds = self._to_temp_dataset().sel(
   1272             indexers=indexers,
   1273             drop=drop,

~\anaconda3\lib\site-packages\xarray\core\dataset.py in sel(self, indexers, method, tolerance, drop, **indexers_kwargs)
   2363         """
   2364         indexers = either_dict_or_kwargs(indexers, indexers_kwargs, "sel")
-> 2365         pos_indexers, new_indexes = remap_label_indexers(
   2366             self, indexers=indexers, method=method, tolerance=tolerance
   2367         )

~\anaconda3\lib\site-packages\xarray\core\coordinates.py in remap_label_indexers(obj, indexers, method, tolerance, **indexers_kwargs)
    419     }
    420 
--> 421     pos_indexers, new_indexes = indexing.remap_label_indexers(
    422         obj, v_indexers, method=method, tolerance=tolerance
    423     )

~\anaconda3\lib\site-packages\xarray\core\indexing.py in remap_label_indexers(data_obj, indexers, method, tolerance)
    272             coords_dtype = data_obj.coords[dim].dtype
    273             label = maybe_cast_to_coords_dtype(label, coords_dtype)
--> 274             idxr, new_idx = convert_label_indexer(index, label, dim, method, tolerance)
    275             pos_indexers[dim] = idxr
    276             if new_idx is not None:

~\anaconda3\lib\site-packages\xarray\core\indexing.py in convert_label_indexer(index, label, index_name, method, tolerance)
    189                 indexer = index.get_loc(label_value)
    190             else:
--> 191                 indexer = index.get_loc(label_value, method=method, tolerance=tolerance)
    192         elif label.dtype.kind == "b":
    193             indexer = label

~\anaconda3\lib\site-packages\pandas\core\indexes\base.py in get_loc(self, key, method, tolerance)
   3361                 return self._engine.get_loc(casted_key)
   3362             except KeyError as err:
-> 3363                 raise KeyError(key) from err
   3364 
   3365         if is_scalar(key) and isna(key) and not self.hasnans:

KeyError: 'JJAS'

Solution

  • Indeed, grouping by "time.season" will only split your data into "DJF", "MAM", "JJA", and "SON". For other combinations of months you will need to define your own mask(s) to apply when taking a mean. For "JJAS" I often use something like this:

    jjas = dset.time.dt.month.isin(range(6, 10))
    clim = dset.sel(time=jjas).mean("time")