Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
P
pymistral
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Deploy
Releases
Container Registry
Model registry
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Aaron Spring
pymistral
Commits
f03c38f9
Commit
f03c38f9
authored
3 years ago
by
Aaron Spring
Browse files
Options
Downloads
Patches
Plain Diff
xoak example
parent
bbdb1533
No related branches found
Branches containing commit
No related tags found
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
ci/pymistral.yml
+14
-10
14 additions, 10 deletions
ci/pymistral.yml
notebooks/xarray_xoak_ICON.ipynb
+356
-0
356 additions, 0 deletions
notebooks/xarray_xoak_ICON.ipynb
with
370 additions
and
10 deletions
ci/pymistral.yml
+
14
−
10
View file @
f03c38f9
...
...
@@ -3,7 +3,8 @@ channels:
-
conda-forge
dependencies
:
-
bokeh
-
cartopy
-
cartopy>=0.18
-
matplotlib>=3.3
-
cdo
-
dask
-
dask-jobqueue
...
...
@@ -20,9 +21,6 @@ dependencies:
-
intake
-
intake-xarray
-
hvplot
-
geoviews
-
holoviews
-
pytest<5.4.0
-
pytest-cov
-
pytest-sugar
-
nb_conda_kernels
...
...
@@ -34,15 +32,21 @@ dependencies:
-
pynio
-
flake8
-
nc-time-axis
-
xrviz
-
xhistogram
-
nodejs>=10.0.0
-
nb_black
-
xoak
-
climpred
-
regionmask
-
pip
:
-
git+https://github.com/jbusecke/cmip6_preprocessing.git
-
git+https://github.com/xgcm/xgcm.git
-
git+https://github.com/xgcm/xrft.git
-
git+https://github.com/mathause/regionmask.git
-
cmip6_preprocessing
-
xgcm
-
git+https://github.com/intake/intake-esm.git
-
pre-commit
-
pytest-lazy-fixture
-
pytest-tldr
-
git+https://github.com/dask/dask-labextension.git
-
git+https://github.com/intake/intake_geopandas.git
-
git+https://github.com/NCAR/intake-thredds.git
#- git+https://github.com/intake/intake.git
-
git+https://github.com/intake/intake-xarray.git
-
git+https://github.com/intake/filesystem_spec.git
This diff is collapsed.
Click to expand it.
notebooks/xarray_xoak_ICON.ipynb
0 → 100644
+
356
−
0
View file @
f03c38f9
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# `xarray` and `ICON`"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import xarray as xr\n",
"xr.set_options(display_style='text')\n",
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"import matplotlib\n",
"import cartopy.crs as ccrs\n",
"import cartopy as cp"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# `xoak`"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- https://xoak.readthedocs.io/en/latest/examples/introduction.html\n",
"- https://xoak.readthedocs.io/en/latest/examples/dask_support.html"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import xoak"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def rad_to_deg(ds):\n",
" \"\"\"Convert radian units to deg.\"\"\"\n",
" #ds.coords.compute()\n",
" for c in ds.coords:\n",
" if 'units' in ds[c].attrs:\n",
" if ds[c].attrs['units'] == 'radian':\n",
" print(f'convert {c} from rad to deg')\n",
" ds[c] = ds[c]* 180./np.pi\n",
" ds[c].attrs['units'] = 'degrees'\n",
" elif 'bnds' in c:\n",
" print(f'convert {c} from rad to deg')\n",
" ds[c] = ds[c]* 180./np.pi\n",
" ds[c].attrs['units'] = 'degrees'\n",
" return ds"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"#igrid = xr.open_dataset('/work/mh0727/m300732/icon-oes-hamocc/experiments/ler0956/icon_grid_0036_R02B04_O.nc')\n",
"#igrid = rad_to_deg(igrid)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# ICON output I want to work with\n",
"ds = xr.open_dataset('/work/mh0727/m300732/icon-oes-hamocc/experiments/ler0956/ler0956_hamocc_34500101T000000Z.nc',\n",
" chunks={'time': 1})"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# move from data_vars to coords\n",
"ds = ds.set_coords(['clon_bnds','clat_bnds'])\n",
"\n",
"ds = rad_to_deg(ds)\n",
"# \n",
"ds['phyp'] # ncells is dimension"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# new grid I want to work on\n",
"mpiom_grid = xr.open_dataset('/home/mpim/m300524/mpiom_fx.nc')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## remap with xoak"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# set xoak index\n",
"ds.xoak.set_index(['clat', 'clon'], 'sklearn_geo_balltree')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from dask.diagnostics import ProgressBar\n",
"import dask\n",
"with ProgressBar(), dask.config.set(scheduler='processes'):\n",
" ds_selection = ds.xoak.sel(clat=mpiom_grid.lat, clon=mpiom_grid.lon)\n",
"\n",
"# %time ds_selection = ds.xoak.sel(clat=mpiom_grid.lat, clon=mpiom_grid.lon) # also runs without dask scheduler\n",
"print('remapping',ds.nbytes/1e6,'MB to ',ds_selection.nbytes/1e6,'MB')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# all lazy dask arrays\n",
"ds_selection['phyp'] # ncells is no dimension anymore, but x and y"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## plot remapped with `xarray.plot()`"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"ds_selection['phyp'].isel(depth=0).plot(col='time', col_wrap=5, robust=True, yincrease=False)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## plot remapped with `pymistral.plot()` wrapping xarray and cartopy"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import pymistral\n",
"ds_selection['phyp'].isel(depth=0).rename({'clon':'lon','clat':'lat'}).compute().plot_map(col='time',col_wrap=3,robust=True, aspect=2, feature='land')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Triangular plotting\n",
"\n",
"plotting the triangles with `plt.tripcolor` from `xarray`"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- could be handle by accessor: http://xarray.pydata.org/en/stable/internals/extending-xarray.html\n",
"- rewrite nicer with xarray instead of np commands where possible"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"@xr.register_dataset_accessor('icon')\n",
"class CartopyMap(object):\n",
" def __init__(self, xarray_obj):\n",
" self._obj = xarray_obj\n",
"\n",
" def plot(self,\n",
" v=None,\n",
" ax=None,\n",
" proj=ccrs.PlateCarree(),\n",
" robust=False,\n",
" **tripcolor_kwargs\n",
" ):\n",
" \"\"\"\n",
" Plot the variable v from an xr.Dataset.\n",
" \n",
" Note: xr.DataArray.icon.plot() would be nicer,\n",
" but the xr.DataArray doesnt carry the neccessary clon_bnds and clat_bnds coords.\n",
" \n",
" Also having some issues how to get the plot nice without buggy triangle,\n",
" but that happened also in matplotlib.\n",
" \n",
" Ideally, this plot function could work like xr.DataArray.plot(col, row, vmin, vmax, robust, ...)\n",
" \"\"\"\n",
" da = self._obj\n",
" # --- Triangulation\n",
" ntr = da.clon.size\n",
" clon_bnds_rs = da['clon_bnds'].values.reshape(ntr*3)\n",
" clat_bnds_rs = da['clat_bnds'].values.reshape(ntr*3)\n",
" triangles = np.arange(ntr*3).reshape(ntr,3)\n",
" Tri = matplotlib.tri.Triangulation(clon_bnds_rs, clat_bnds_rs, triangles=triangles)\n",
"\n",
" if isinstance(da,xr.Dataset):\n",
" if v is None:\n",
" v=list(da.data_vars)\n",
" if len(v)>0:\n",
" v=v[0] # take first variable\n",
" da=da[v]\n",
" else:\n",
" da=da[v]\n",
"\n",
" vmin = tripcolor_kwargs.pop('vmin',None)\n",
" vmax = tripcolor_kwargs.pop('vmax',None)\n",
" if vmin is None and vmax is None and robust:\n",
" vmin = da.quantile(0.02).values\n",
" vmax = da.quantile(.98).values\n",
" \n",
" # what if more than two dims: see xr.facetgrid\n",
" fig, axes = plt.subplots(subplot_kw=dict(projection=proj),figsize=(8,4))\n",
" # best would be to add tripcolor to xarray\n",
" hm = axes.tripcolor(Tri,\n",
" da,\n",
" vmin=vmin,\n",
" vmax=vmax,\n",
" #edgecolors='k',\n",
" #lw=0.01,\n",
" transform=ccrs.PlateCarree(),\n",
" alpha=.5,\n",
" **tripcolor_kwargs\n",
" )\n",
" # now add features, labels etc\n",
" axes.add_feature(cp.feature.LAND, zorder=0)\n",
" #axes.set_extent((-178, 178, -88, 88), crs=ccrs.PlateCarree())\n",
" cb = plt.colorbar(mappable=hm, ax=axes, extend='both')\n",
" ## use metadata\n",
" title_str = ''\n",
" title_labels = [c for c in da.coords if da.coords[c].size == 1]\n",
" for l in title_labels:\n",
" title_str += f', {l} = {str(da[l].astype(str).values)}'\n",
" axes.set_title(title_str[1:])\n",
" cb.set_label(f'{da.attrs[\"long_name\"]}\\n[{da.attrs[\"units\"]}]', rotation = 90)\n",
" # add x,y ticks and labels\n",
" return axes"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"ds.isel(depth=0,time=2).icon.plot('phyp', cmap='RdBu')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"ds.isel(depth=0,time=2).icon.plot('po4', robust=True)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python [conda env:pymistral]",
"language": "python",
"name": "conda-env-pymistral-py"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.6"
}
},
"nbformat": 4,
"nbformat_minor": 4
}
%% Cell type:markdown id: tags:
# `xarray` and `ICON`
%% Cell type:code id: tags:
```
python
import
xarray
as
xr
xr
.
set_options
(
display_style
=
'
text
'
)
import
numpy
as
np
import
matplotlib.pyplot
as
plt
import
matplotlib
import
cartopy.crs
as
ccrs
import
cartopy
as
cp
```
%% Cell type:markdown id: tags:
# `xoak`
%% Cell type:markdown id: tags:
-
https://xoak.readthedocs.io/en/latest/examples/introduction.html
-
https://xoak.readthedocs.io/en/latest/examples/dask_support.html
%% Cell type:code id: tags:
```
python
import
xoak
```
%% Cell type:code id: tags:
```
python
def
rad_to_deg
(
ds
):
"""
Convert radian units to deg.
"""
#ds.coords.compute()
for
c
in
ds
.
coords
:
if
'
units
'
in
ds
[
c
].
attrs
:
if
ds
[
c
].
attrs
[
'
units
'
]
==
'
radian
'
:
print
(
f
'
convert
{
c
}
from rad to deg
'
)
ds
[
c
]
=
ds
[
c
]
*
180.
/
np
.
pi
ds
[
c
].
attrs
[
'
units
'
]
=
'
degrees
'
elif
'
bnds
'
in
c
:
print
(
f
'
convert
{
c
}
from rad to deg
'
)
ds
[
c
]
=
ds
[
c
]
*
180.
/
np
.
pi
ds
[
c
].
attrs
[
'
units
'
]
=
'
degrees
'
return
ds
```
%% Cell type:code id: tags:
```
python
#igrid = xr.open_dataset('/work/mh0727/m300732/icon-oes-hamocc/experiments/ler0956/icon_grid_0036_R02B04_O.nc')
#igrid = rad_to_deg(igrid)
```
%% Cell type:code id: tags:
```
python
``
`
%%
Cell
type
:
code
id
:
tags
:
```
python
# ICON output I want to work with
ds = xr.open_dataset('/work/mh0727/m300732/icon-oes-hamocc/experiments/ler0956/ler0956_hamocc_34500101T000000Z.nc',
chunks={'time': 1})
```
%% Cell type:code id: tags:
```
python
# move from data_vars to coords
ds = ds.set_coords(['clon_bnds','clat_bnds'])
ds = rad_to_deg(ds)
#
ds['phyp'] # ncells is dimension
```
%% Cell type:code id: tags:
```
python
# new grid I want to work on
mpiom_grid = xr.open_dataset('/home/mpim/m300524/mpiom_fx.nc')
```
%% Cell type:markdown id: tags:
## remap with xoak
%% Cell type:code id: tags:
```
python
# set xoak index
ds.xoak.set_index(['clat', 'clon'], 'sklearn_geo_balltree')
```
%% Cell type:code id: tags:
```
python
from dask.diagnostics import ProgressBar
import dask
with ProgressBar(), dask.config.set(scheduler='processes'):
ds_selection = ds.xoak.sel(clat=mpiom_grid.lat, clon=mpiom_grid.lon)
# %time ds_selection = ds.xoak.sel(clat=mpiom_grid.lat, clon=mpiom_grid.lon) # also runs without dask scheduler
print('remapping',ds.nbytes/1e6,'MB to ',ds_selection.nbytes/1e6,'MB')
```
%% Cell type:code id: tags:
```
python
# all lazy dask arrays
ds_selection['phyp'] # ncells is no dimension anymore, but x and y
```
%% Cell type:markdown id: tags:
## plot remapped with `xarray.plot()`
%% Cell type:code id: tags:
```
python
ds_selection['phyp'].isel(depth=0).plot(col='time', col_wrap=5, robust=True, yincrease=False)
```
%% Cell type:markdown id: tags:
## plot remapped with `pymistral.plot()` wrapping xarray and cartopy
%% Cell type:code id: tags:
```
python
import pymistral
ds_selection['phyp'].isel(depth=0).rename({'clon':'lon','clat':'lat'}).compute().plot_map(col='time',col_wrap=3,robust=True, aspect=2, feature='land')
```
%% Cell type:code id: tags:
```
python
```
%% Cell type:code id: tags:
```
python
```
%% Cell type:markdown id: tags:
# Triangular plotting
plotting the triangles with `plt.tripcolor` from `xarray`
%% Cell type:markdown id: tags:
- could be handle by accessor: http://xarray.pydata.org/en/stable/internals/extending-xarray.html
- rewrite nicer with xarray instead of np commands where possible
%% Cell type:code id: tags:
```
python
@xr.register_dataset_accessor('icon')
class CartopyMap(object):
def __init__(self, xarray_obj):
self._obj = xarray_obj
def plot(self,
v=None,
ax=None,
proj=ccrs.PlateCarree(),
robust=False,
**tripcolor_kwargs
):
"""
Plot the variable v from an xr.Dataset.
Note: xr.DataArray.icon.plot() would be nicer,
but the xr.DataArray doesnt carry the neccessary clon_bnds and clat_bnds coords.
Also having some issues how to get the plot nice without buggy triangle,
but that happened also in matplotlib.
Ideally, this plot function could work like xr.DataArray.plot(col, row, vmin, vmax, robust, ...)
"""
da = self._obj
# --- Triangulation
ntr = da.clon.size
clon_bnds_rs = da['clon_bnds'].values.reshape(ntr*3)
clat_bnds_rs = da['clat_bnds'].values.reshape(ntr*3)
triangles = np.arange(ntr*3).reshape(ntr,3)
Tri = matplotlib.tri.Triangulation(clon_bnds_rs, clat_bnds_rs, triangles=triangles)
if isinstance(da,xr.Dataset):
if v is None:
v=list(da.data_vars)
if len(v)>0:
v=v[0] # take first variable
da=da[v]
else:
da=da[v]
vmin = tripcolor_kwargs.pop('vmin',None)
vmax = tripcolor_kwargs.pop('vmax',None)
if vmin is None and vmax is None and robust:
vmin = da.quantile(0.02).values
vmax = da.quantile(.98).values
# what if more than two dims: see xr.facetgrid
fig, axes = plt.subplots(subplot_kw=dict(projection=proj),figsize=(8,4))
# best would be to add tripcolor to xarray
hm = axes.tripcolor(Tri,
da,
vmin=vmin,
vmax=vmax,
#edgecolors='k',
#lw=0.01,
transform=ccrs.PlateCarree(),
alpha=.5,
**tripcolor_kwargs
)
# now add features, labels etc
axes.add_feature(cp.feature.LAND, zorder=0)
#axes.set_extent((-178, 178, -88, 88), crs=ccrs.PlateCarree())
cb = plt.colorbar(mappable=hm, ax=axes, extend='both')
## use metadata
title_str = ''
title_labels = [c for c in da.coords if da.coords[c].size == 1]
for l in title_labels:
title_str += f', {l} = {str(da[l].astype(str).values)}'
axes.set_title(title_str[1:])
cb.set_label(f'{da.attrs["long_name"]}\n[{da.attrs["units"]}]', rotation = 90)
# add x,y ticks and labels
return axes
```
%% Cell type:code id: tags:
```
python
ds.isel(depth=0,time=2).icon.plot('phyp', cmap='RdBu')
```
%% Cell type:code id: tags:
```
python
ds.isel(depth=0,time=2).icon.plot('po4', robust=True)
```
%% Cell type:code id: tags:
```
python
```
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment