From e15ed7370aa285d4d71bf1c9175c53acdb5a3e8c Mon Sep 17 00:00:00 2001
From: Geert Jan Bex <geertjan.bex@uhasselt.be>
Date: Mon, 20 Jan 2020 09:22:43 +0100
Subject: [PATCH 1/6] Update conda environment file

---
 ...n_for_data_science_linux64_conda_specs.txt | 38 ++++++++++---------
 1 file changed, 20 insertions(+), 18 deletions(-)

diff --git a/python_for_data_science_linux64_conda_specs.txt b/python_for_data_science_linux64_conda_specs.txt
index dec34ff..b30354c 100644
--- a/python_for_data_science_linux64_conda_specs.txt
+++ b/python_for_data_science_linux64_conda_specs.txt
@@ -6,6 +6,7 @@ https://repo.anaconda.com/pkgs/main/linux-64/_libgcc_mutex-0.1-main.conda
 https://repo.anaconda.com/pkgs/main/linux-64/blas-1.0-mkl.conda
 https://repo.anaconda.com/pkgs/main/linux-64/ca-certificates-2019.11.27-0.tar.bz2
 https://repo.anaconda.com/pkgs/main/linux-64/intel-openmp-2019.4-243.conda
+https://repo.anaconda.com/pkgs/main/linux-64/ld_impl_linux-64-2.33.1-h53a641e_7.conda
 https://repo.anaconda.com/pkgs/main/linux-64/libgfortran-ng-7.3.0-hdf63c60_0.conda
 https://repo.anaconda.com/pkgs/main/linux-64/libstdcxx-ng-9.1.0-hdf63c60_0.conda
 https://repo.anaconda.com/pkgs/main/linux-64/poppler-data-0.4.9-0.conda
@@ -20,19 +21,20 @@ https://repo.anaconda.com/pkgs/main/linux-64/gmp-6.1.2-h6c8ec71_1.conda
 https://repo.anaconda.com/pkgs/main/linux-64/icu-58.2-h9c2bf20_1.conda
 https://repo.anaconda.com/pkgs/main/linux-64/jpeg-9b-h024ee3a_2.conda
 https://repo.anaconda.com/pkgs/main/linux-64/json-c-0.13.1-h1bed415_0.conda
-https://repo.continuum.io/pkgs/main/linux-64/libffi-3.2.1-hd88cf55_4.tar.bz2
+https://repo.anaconda.com/pkgs/main/linux-64/libffi-3.2.1-hd88cf55_4.conda
 https://repo.anaconda.com/pkgs/main/linux-64/libsodium-1.0.16-h1bed415_0.conda
 https://repo.anaconda.com/pkgs/main/linux-64/libspatialindex-1.9.3-he6710b0_0.tar.bz2
 https://repo.anaconda.com/pkgs/main/linux-64/libuuid-1.0.3-h1bed415_2.conda
 https://repo.anaconda.com/pkgs/main/linux-64/libxcb-1.13-h1bed415_1.conda
 https://repo.anaconda.com/pkgs/main/linux-64/lz4-c-1.8.1.2-h14c3975_0.conda
 https://repo.anaconda.com/pkgs/main/linux-64/ncurses-6.1-he6710b0_1.conda
+https://repo.anaconda.com/pkgs/main/linux-64/nodejs-10.13.0-he6710b0_0.conda
 https://repo.anaconda.com/pkgs/main/linux-64/openssl-1.1.1d-h7b6447c_3.tar.bz2
 https://repo.anaconda.com/pkgs/main/linux-64/pcre-8.43-he6710b0_0.conda
 https://repo.anaconda.com/pkgs/main/linux-64/pixman-0.38.0-h7b6447c_0.conda
 https://repo.anaconda.com/pkgs/main/linux-64/tbb-2018.0.5-h6bb024c_0.conda
 https://repo.anaconda.com/pkgs/main/linux-64/xz-5.2.4-h14c3975_4.conda
-https://repo.continuum.io/pkgs/main/linux-64/yaml-0.1.7-had09818_2.tar.bz2
+https://repo.anaconda.com/pkgs/main/linux-64/yaml-0.1.7-had09818_2.conda
 https://repo.anaconda.com/pkgs/main/linux-64/zlib-1.2.11-h7b6447c_3.conda
 https://repo.anaconda.com/pkgs/main/linux-64/glib-2.63.1-h5a9c865_0.tar.bz2
 https://repo.anaconda.com/pkgs/main/linux-64/hdf4-4.2.13-h3ca952b_2.conda
@@ -62,8 +64,8 @@ https://repo.anaconda.com/pkgs/main/linux-64/libcurl-7.67.0-h20c2e04_0.tar.bz2
 https://repo.anaconda.com/pkgs/main/linux-64/libpq-11.2-h20c2e04_0.conda
 https://repo.anaconda.com/pkgs/main/linux-64/openjpeg-2.3.0-h05c96fa_1.conda
 https://repo.anaconda.com/pkgs/main/linux-64/proj-6.2.1-haa6030c_0.conda
-https://repo.anaconda.com/pkgs/main/linux-64/python-3.7.5-h0371630_0.conda
-https://repo.anaconda.com/pkgs/main/linux-64/asn1crypto-1.2.0-py37_0.tar.bz2
+https://repo.anaconda.com/pkgs/main/linux-64/python-3.7.6-h0371630_2.conda
+https://repo.anaconda.com/pkgs/main/linux-64/asn1crypto-1.3.0-py37_0.conda
 https://repo.anaconda.com/pkgs/main/noarch/attrs-19.3.0-py_0.tar.bz2
 https://repo.anaconda.com/pkgs/main/linux-64/backcall-0.1.0-py37_0.conda
 https://repo.anaconda.com/pkgs/main/linux-64/cairo-1.14.12-h8948797_3.conda
@@ -93,7 +95,7 @@ https://repo.anaconda.com/pkgs/main/linux-64/postgresql-11.2-h20c2e04_0.conda
 https://repo.anaconda.com/pkgs/main/noarch/prometheus_client-0.7.1-py_0.tar.bz2
 https://repo.anaconda.com/pkgs/main/linux-64/ptyprocess-0.6.0-py37_0.conda
 https://repo.anaconda.com/pkgs/main/linux-64/pycparser-2.19-py37_0.conda
-https://repo.anaconda.com/pkgs/main/noarch/pyparsing-2.4.5-py_0.tar.bz2
+https://repo.anaconda.com/pkgs/main/noarch/pyparsing-2.4.6-py_0.conda
 https://repo.anaconda.com/pkgs/main/linux-64/pyproj-2.4.1-py37h2ea87da_0.conda
 https://repo.anaconda.com/pkgs/main/linux-64/pysocks-1.7.1-py37_0.tar.bz2
 https://repo.anaconda.com/pkgs/main/noarch/pytz-2019.3-py_0.tar.bz2
@@ -105,31 +107,31 @@ https://repo.anaconda.com/pkgs/main/linux-64/send2trash-1.5.0-py37_0.conda
 https://repo.anaconda.com/pkgs/main/linux-64/sip-4.19.8-py37hf484d3e_0.conda
 https://repo.anaconda.com/pkgs/main/linux-64/six-1.13.0-py37_0.tar.bz2
 https://repo.anaconda.com/pkgs/main/linux-64/soupsieve-1.9.5-py37_0.tar.bz2
-https://repo.anaconda.com/pkgs/main/linux-64/sqlalchemy-1.3.11-py37h7b6447c_0.tar.bz2
+https://repo.anaconda.com/pkgs/main/linux-64/sqlalchemy-1.3.12-py37h7b6447c_0.conda
 https://repo.anaconda.com/pkgs/main/noarch/testpath-0.4.4-py_0.tar.bz2
 https://repo.anaconda.com/pkgs/main/noarch/toolz-0.10.0-py_0.tar.bz2
 https://repo.anaconda.com/pkgs/main/linux-64/tornado-6.0.3-py37h7b6447c_0.conda
 https://repo.anaconda.com/pkgs/main/linux-64/wcwidth-0.1.7-py37_0.conda
 https://repo.anaconda.com/pkgs/main/linux-64/webencodings-0.5.1-py37_1.conda
 https://repo.anaconda.com/pkgs/main/linux-64/xlrd-1.2.0-py37_0.conda
-https://repo.anaconda.com/pkgs/main/linux-64/beautifulsoup4-4.8.1-py37_0.tar.bz2
+https://repo.anaconda.com/pkgs/main/linux-64/beautifulsoup4-4.8.2-py37_0.conda
 https://repo.anaconda.com/pkgs/main/linux-64/cffi-1.13.2-py37h2e261b9_0.tar.bz2
 https://repo.anaconda.com/pkgs/main/noarch/click-plugins-1.1.1-py_0.tar.bz2
 https://repo.anaconda.com/pkgs/main/linux-64/cligj-0.5.0-py37_0.conda
 https://repo.anaconda.com/pkgs/main/linux-64/cycler-0.10.0-py37_0.conda
-https://repo.anaconda.com/pkgs/main/linux-64/jedi-0.15.1-py37_0.conda
+https://repo.anaconda.com/pkgs/main/linux-64/jedi-0.15.2-py37_0.conda
 https://repo.anaconda.com/pkgs/main/linux-64/libdap4-3.19.1-h6ec2957_0.conda
 https://repo.anaconda.com/pkgs/main/linux-64/libnetcdf-4.6.1-h11d0813_2.conda
 https://repo.anaconda.com/pkgs/main/linux-64/mkl-service-2.3.0-py37he904b0f_0.conda
-https://repo.anaconda.com/pkgs/main/noarch/packaging-19.2-py_0.tar.bz2
+https://repo.anaconda.com/pkgs/main/noarch/packaging-20.0-py_0.conda
 https://repo.anaconda.com/pkgs/main/linux-64/pexpect-4.7.0-py37_0.conda
-https://repo.anaconda.com/pkgs/main/linux-64/pillow-6.2.1-py37h34e0f95_0.tar.bz2
+https://repo.anaconda.com/pkgs/main/linux-64/pillow-7.0.0-py37hb39fc2d_0.conda
 https://repo.anaconda.com/pkgs/main/linux-64/poppler-0.65.0-h581218d_1.conda
 https://repo.anaconda.com/pkgs/main/linux-64/pyqt-5.9.2-py37h05f1152_2.conda
 https://repo.anaconda.com/pkgs/main/linux-64/pyrsistent-0.15.6-py37h7b6447c_0.tar.bz2
 https://repo.anaconda.com/pkgs/main/noarch/python-dateutil-2.8.1-py_0.tar.bz2
 https://repo.anaconda.com/pkgs/main/noarch/pyviz_comms-0.7.2-py_0.tar.bz2
-https://repo.anaconda.com/pkgs/main/linux-64/setuptools-42.0.2-py37_0.tar.bz2
+https://repo.anaconda.com/pkgs/main/linux-64/setuptools-44.0.0-py37_0.conda
 https://repo.anaconda.com/pkgs/main/linux-64/terminado-0.8.3-py37_0.tar.bz2
 https://repo.anaconda.com/pkgs/main/linux-64/tiledb-1.6.3-h1fb8f14_0.conda
 https://repo.anaconda.com/pkgs/main/linux-64/traitlets-4.3.3-py37_0.tar.bz2
@@ -142,7 +144,7 @@ https://repo.anaconda.com/pkgs/main/linux-64/jupyter_core-4.6.1-py37_0.tar.bz2
 https://repo.anaconda.com/pkgs/main/linux-64/libgdal-3.0.2-h27ab9cc_0.conda
 https://repo.anaconda.com/pkgs/main/noarch/munch-2.5.0-py_0.tar.bz2
 https://repo.anaconda.com/pkgs/main/noarch/networkx-2.4-py_0.tar.bz2
-https://repo.anaconda.com/pkgs/main/linux-64/numpy-base-1.17.4-py37hde5b4d6_0.conda
+https://repo.anaconda.com/pkgs/main/linux-64/numpy-base-1.18.1-py37hde5b4d6_0.conda
 https://repo.anaconda.com/pkgs/main/noarch/pygments-2.5.2-py_0.tar.bz2
 https://repo.anaconda.com/pkgs/main/linux-64/wheel-0.33.6-py37_0.tar.bz2
 https://conda.anaconda.org/conda-forge/noarch/branca-0.3.1-py_0.tar.bz2
@@ -151,28 +153,28 @@ https://repo.anaconda.com/pkgs/main/linux-64/jupyter_client-5.3.4-py37_0.tar.bz2
 https://repo.anaconda.com/pkgs/main/linux-64/pip-19.3.1-py37_0.tar.bz2
 https://repo.anaconda.com/pkgs/main/noarch/prompt_toolkit-2.0.10-py_0.tar.bz2
 https://repo.anaconda.com/pkgs/main/linux-64/pyopenssl-19.1.0-py37_0.tar.bz2
-https://repo.anaconda.com/pkgs/main/linux-64/ipython-7.10.2-py37h39e3cac_0.conda
+https://repo.anaconda.com/pkgs/main/linux-64/ipython-7.11.1-py37h39e3cac_0.conda
 https://repo.anaconda.com/pkgs/main/linux-64/nbformat-4.4.0-py37_0.conda
 https://repo.anaconda.com/pkgs/main/linux-64/urllib3-1.25.7-py37_0.tar.bz2
-https://repo.anaconda.com/pkgs/main/linux-64/ipykernel-5.1.3-py37h39e3cac_0.tar.bz2
+https://repo.anaconda.com/pkgs/main/linux-64/ipykernel-5.1.3-py37h39e3cac_1.conda
 https://repo.anaconda.com/pkgs/main/linux-64/nbconvert-5.6.1-py37_0.tar.bz2
 https://repo.anaconda.com/pkgs/main/linux-64/requests-2.22.0-py37_1.tar.bz2
 https://repo.anaconda.com/pkgs/main/linux-64/jupyter_console-6.0.0-py37_0.conda
 https://repo.anaconda.com/pkgs/main/linux-64/notebook-6.0.2-py37_0.tar.bz2
-https://repo.anaconda.com/pkgs/main/noarch/qtconsole-4.6.0-py_0.tar.bz2
+https://repo.anaconda.com/pkgs/main/noarch/qtconsole-4.6.0-py_1.conda
 https://repo.anaconda.com/pkgs/main/noarch/jupyterlab_server-1.0.6-py_0.tar.bz2
 https://repo.anaconda.com/pkgs/main/linux-64/widgetsnbextension-3.5.1-py37_0.conda
 https://repo.anaconda.com/pkgs/main/noarch/ipywidgets-7.5.1-py_0.tar.bz2
-https://repo.anaconda.com/pkgs/main/noarch/jupyterlab-1.2.4-pyhf63ae98_0.conda
+https://repo.anaconda.com/pkgs/main/noarch/jupyterlab-1.2.5-pyhf63ae98_0.conda
 https://repo.anaconda.com/pkgs/main/linux-64/jupyter-1.0.0-py37_7.conda
 https://conda.anaconda.org/conda-forge/noarch/vincent-0.4.4-py_1.tar.bz2
 https://repo.anaconda.com/pkgs/main/linux-64/bokeh-1.4.0-py37_0.tar.bz2
 https://repo.anaconda.com/pkgs/main/linux-64/gdal-3.0.2-py37hbb2a789_0.conda
 https://repo.anaconda.com/pkgs/main/linux-64/matplotlib-3.1.1-py37h5429711_0.conda
-https://repo.anaconda.com/pkgs/main/noarch/holoviews-1.12.7-py_0.tar.bz2
 https://repo.anaconda.com/pkgs/main/linux-64/mkl_fft-1.0.15-py37ha843d7b_0.tar.bz2
 https://repo.anaconda.com/pkgs/main/linux-64/mkl_random-1.1.0-py37hd6b4f25_0.conda
-https://repo.anaconda.com/pkgs/main/linux-64/numpy-1.17.4-py37hc1035e2_0.conda
+https://repo.anaconda.com/pkgs/main/linux-64/numpy-1.18.1-py37h4f9e942_0.conda
+https://repo.anaconda.com/pkgs/main/noarch/holoviews-1.12.7-py_0.tar.bz2
 https://repo.anaconda.com/pkgs/main/linux-64/pandas-0.25.3-py37he6710b0_0.tar.bz2
 https://repo.anaconda.com/pkgs/main/linux-64/scipy-1.3.2-py37h7c811a0_0.conda
 https://repo.anaconda.com/pkgs/main/linux-64/shapely-1.6.4-py37hc5e8c75_0.conda

From baa55ee363b9197dbabbc56db9ce1c642e48f3db Mon Sep 17 00:00:00 2001
From: Geert Jan Bex <geertjan.bex@uhasselt.be>
Date: Mon, 20 Jan 2020 09:24:19 +0100
Subject: [PATCH 2/6] Update conda environment

---
 environment.yml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/environment.yml b/environment.yml
index 268964e..e75444a 100644
--- a/environment.yml
+++ b/environment.yml
@@ -7,10 +7,12 @@ dependencies:
   - folium
   - geopandas
   - holoviews
+  - ipywidgets
   - jupyter
   - jupyterlab
   - matplotlib
   - networkx
+  - nodejs
   - pandas
   - python=3.7
   - scipy

From 2809c90a3a58237612dc27aed734d1bbc289c14d Mon Sep 17 00:00:00 2001
From: Geert Jan Bex <geertjan.bex@uhasselt.be>
Date: Mon, 20 Jan 2020 09:52:12 +0100
Subject: [PATCH 3/6] Add illustration of xarray library

---
 source-code/README.md                 |    2 +
 source-code/xarray/.gitignore         |    1 +
 source-code/xarray/README.md          |    8 +
 source-code/xarray/xarray_intro.ipynb | 2272 +++++++++++++++++++++++++
 4 files changed, 2283 insertions(+)
 create mode 100644 source-code/xarray/.gitignore
 create mode 100644 source-code/xarray/README.md
 create mode 100644 source-code/xarray/xarray_intro.ipynb

diff --git a/source-code/README.md b/source-code/README.md
index 65ed2fb..60fefd6 100644
--- a/source-code/README.md
+++ b/source-code/README.md
@@ -33,3 +33,5 @@ to create it.  There is some material not covered in the presentation as well.
 * [1seaborn`]:(seaborn): illustrations of using Seaborn to create plots.
 * [`web-scraping`](web-scraping): illustration of web scraping using beautiful soup
   and graph representation using networkx.
+* [`xarray`](xarray): illustrates the xarray library for pandas-like operations
+  on multi-dimensional arrays.
diff --git a/source-code/xarray/.gitignore b/source-code/xarray/.gitignore
new file mode 100644
index 0000000..d57580f
--- /dev/null
+++ b/source-code/xarray/.gitignore
@@ -0,0 +1 @@
+*.nc
diff --git a/source-code/xarray/README.md b/source-code/xarray/README.md
new file mode 100644
index 0000000..59ad484
--- /dev/null
+++ b/source-code/xarray/README.md
@@ -0,0 +1,8 @@
+# Xarray
+
+xarray is a Python package to represent numerical data with metadata.  In that respect it is
+a hybrid between numpy and pandas.
+
+## What is it?
+
+1. `xarray_intro.ipynb`: Jupyter notebook introducing some of xarray's features.
diff --git a/source-code/xarray/xarray_intro.ipynb b/source-code/xarray/xarray_intro.ipynb
new file mode 100644
index 0000000..44958ac
--- /dev/null
+++ b/source-code/xarray/xarray_intro.ipynb
@@ -0,0 +1,2272 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "toc-hr-collapsed": false
+   },
+   "source": [
+    "# xarray package"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "xarray is a crossbreed between numpy and pandas. It allows to annotate pure numerical (numpy-like) data with indices, attributes and so on."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Required imports"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2019-07-03T04:57:31.798225Z",
+     "start_time": "2019-07-03T04:57:31.776706Z"
+    }
+   },
+   "outputs": [],
+   "source": [
+    "import matplotlib.pyplot as plt\n",
+    "%matplotlib inline\n",
+    "import numpy as np\n",
+    "import pandas as pd\n",
+    "from pandas.plotting import register_matplotlib_converters\n",
+    "register_matplotlib_converters()\n",
+    "import sys\n",
+    "import xarray as xr"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Running example"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Create a 2D array of floating point values that represent temperatures of a plane. The dimensions are named `x` and `y`, and the coordinates for those dimensions are provided."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2019-07-03T04:48:30.222457Z",
+     "start_time": "2019-07-03T04:48:29.895908Z"
+    },
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "<xarray.DataArray (x: 11, y: 11)>\n",
+       "array([[20.060227, 20.343288, 22.493436, 20.886055, 19.599252, 19.9795  ,\n",
+       "        19.463129, 25.567439, 21.672808, 17.00054 , 19.591958],\n",
+       "       [18.393412, 16.544274, 19.472503, 23.419062, 20.918769, 19.231152,\n",
+       "        19.582383, 21.38485 , 22.895528, 19.82586 , 23.447652],\n",
+       "       [21.458348, 21.843564, 22.611372, 18.006569, 20.575531, 21.166873,\n",
+       "        22.006631, 18.940422, 20.571206, 23.026252, 20.922982],\n",
+       "       [22.736496, 21.494013, 20.76477 , 24.218455, 22.423822, 20.844336,\n",
+       "        22.972383, 22.169935, 18.982916, 20.076558, 21.534189],\n",
+       "       [20.385641, 22.899617, 21.14046 , 19.492904, 22.013288, 20.519298,\n",
+       "        17.047163, 24.69833 , 20.749292, 17.556841, 23.444134],\n",
+       "       [22.188399, 21.542768, 21.069173, 20.804404, 19.985631, 21.650881,\n",
+       "        19.957621, 20.733553, 15.845453, 20.586171, 23.194928],\n",
+       "       [20.631938, 20.546089, 21.234935, 18.799045, 23.066751, 19.738352,\n",
+       "        20.043838, 21.464738, 22.404247, 21.243846, 21.816928],\n",
+       "       [21.383564, 23.706478, 23.973886, 19.403355, 22.604506, 16.450427,\n",
+       "        19.649931, 21.500265, 16.411651, 26.416987, 22.197047],\n",
+       "       [21.212505, 22.172344, 20.169168, 21.490327, 17.34986 , 19.617111,\n",
+       "        19.777066, 18.771164, 21.021582, 19.224937, 19.965937],\n",
+       "       [19.058219, 24.294649, 21.671964, 21.274954, 23.989597, 21.86506 ,\n",
+       "        20.249017, 21.804745, 19.50452 , 23.047136, 23.045451],\n",
+       "       [22.091376, 18.088312, 19.849349, 22.912824, 19.700604, 19.021563,\n",
+       "        17.447241, 26.386473, 18.399266, 24.399055, 19.037564]])\n",
+       "Coordinates:\n",
+       "  * x        (x) float64 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0\n",
+       "  * y        (y) float64 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0"
+      ]
+     },
+     "execution_count": 2,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "grid_size = 11\n",
+    "temperature = xr.DataArray(np.random.normal(loc=21.0, scale=2.0, size=(grid_size, grid_size)),\n",
+    "                           dims=('x', 'y'), coords={'x': np.linspace(0.0, 1.0, grid_size),\n",
+    "                                                    'y': np.linspace(0.0, 1.0, grid_size)})\n",
+    "temperature"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Accessing data"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "The elements can be accessed as you would do for a numpy array as well."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2019-07-03T05:01:08.509437Z",
+     "start_time": "2019-07-03T05:01:08.480251Z"
+    }
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "<xarray.DataArray ()>\n",
+       "array(19.472503)\n",
+       "Coordinates:\n",
+       "    x        float64 0.1\n",
+       "    y        float64 0.2"
+      ]
+     },
+     "execution_count": 3,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "temperature[1, 2]"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Note however that the result is a new xarray, althought it contains only a single element.  An advantage of this is that the coordinates are part of the result."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "The values of the xarray `temperature` can now be accessed by index, i.e., the value of the coordinates, e.g., the temperature at $x = 0.1$ and $y = 0.2$ is given by:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2019-07-02T14:46:35.996918Z",
+     "start_time": "2019-07-02T14:46:35.966369Z"
+    }
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "<xarray.DataArray ()>\n",
+       "array(19.472503)\n",
+       "Coordinates:\n",
+       "    x        float64 0.1\n",
+       "    y        float64 0.2"
+      ]
+     },
+     "execution_count": 4,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "temperature.sel(x=0.1, y=0.2)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Note that using `float` coordinates may lead to unexpected results due to round off errors."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2019-07-03T04:59:13.433341Z",
+     "start_time": "2019-07-03T04:59:13.409876Z"
+    }
+   },
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "KeyError for 0.200000000001\n"
+     ]
+    }
+   ],
+   "source": [
+    "try:\n",
+    "    temperature.sel(x=0.1, y=0.200000000001)\n",
+    "except KeyError as e:\n",
+    "    print(f'KeyError for {e}', file=sys.stderr)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "It is straightforward to interpolate, as we'll discuss in a [later section](#Interpolation)."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "xarrays can be indexed by slicing as well.  Note that you need to use the `slice` function."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2019-07-03T07:08:20.915039Z",
+     "start_time": "2019-07-03T07:08:20.841836Z"
+    }
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "<xarray.DataArray (x: 7, y: 2)>\n",
+       "array([[21.843564, 22.611372],\n",
+       "       [21.494013, 20.76477 ],\n",
+       "       [22.899617, 21.14046 ],\n",
+       "       [21.542768, 21.069173],\n",
+       "       [20.546089, 21.234935],\n",
+       "       [23.706478, 23.973886],\n",
+       "       [22.172344, 20.169168]])\n",
+       "Coordinates:\n",
+       "  * x        (x) float64 0.2 0.3 0.4 0.5 0.6 0.7 0.8\n",
+       "  * y        (y) float64 0.1 0.2"
+      ]
+     },
+     "execution_count": 6,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "temperature.sel(x=slice(0.2, 0.8), y=slice(0.1, 0.3))"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "It is also possible to select values from an xarray using integer location indices on specific dimensions without worrying about the layout of the array."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2019-07-03T05:00:57.912906Z",
+     "start_time": "2019-07-03T05:00:57.892762Z"
+    }
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "<xarray.DataArray ()>\n",
+       "array(19.472503)\n",
+       "Coordinates:\n",
+       "    x        float64 0.1\n",
+       "    y        float64 0.2"
+      ]
+     },
+     "execution_count": 7,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "temperature.isel(x=1, y=2)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "A scalar value can be obtained using the `float` constructor."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2019-07-02T14:47:41.855378Z",
+     "start_time": "2019-07-02T14:47:41.842593Z"
+    },
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "19.47250344542894"
+      ]
+     },
+     "execution_count": 8,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "float(temperature.isel(x=1, y=2))"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2019-07-03T07:21:03.186815Z",
+     "start_time": "2019-07-03T07:21:03.145478Z"
+    }
+   },
+   "source": [
+    "As in pandas, direct access to the underlying numpy array is available as well."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2019-07-03T08:57:01.034727Z",
+     "start_time": "2019-07-03T08:57:01.021467Z"
+    }
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "<class 'numpy.ndarray'> float64 (11, 11)\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(type(temperature.values), temperature.values.dtype, temperature.values.shape)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": []
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Metadata"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Like a numpy array, the data type and shape of an xarray can be easily obtained."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2019-07-03T08:59:03.230436Z",
+     "start_time": "2019-07-03T08:59:03.220621Z"
+    }
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "float64 (11, 11)\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(temperature.dtype, temperature.shape)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "The dimensions can be retrieved."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2019-07-03T07:37:15.883407Z",
+     "start_time": "2019-07-03T07:37:15.866205Z"
+    }
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('x', 'y')"
+      ]
+     },
+     "execution_count": 11,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "temperature.dims"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "The coordinates associated with an xarray can be retrieved as well."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2019-07-02T14:50:47.268531Z",
+     "start_time": "2019-07-02T14:50:47.235440Z"
+    }
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "<xarray.DataArray 'x' (x: 11)>\n",
+       "array([0. , 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1. ])\n",
+       "Coordinates:\n",
+       "  * x        (x) float64 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0"
+      ]
+     },
+     "execution_count": 12,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "temperature.coords['x']"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "This can be quite convenient to reuse the same coordinates in a new xarray."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2019-07-03T08:49:44.720587Z",
+     "start_time": "2019-07-03T08:49:44.684016Z"
+    }
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "<xarray.DataArray (x: 11, y: 11)>\n",
+       "array([[109803.901687, 111194.942097, 106939.167658, 112581.874272,\n",
+       "        107370.597966, 105990.707104, 108363.976396, 108281.687394,\n",
+       "        108297.235189, 106382.832734, 112961.88931 ],\n",
+       "       [112114.749396, 108240.793539, 110317.588222, 107689.300553,\n",
+       "        107170.169005, 113727.759334, 112912.602492, 108662.417573,\n",
+       "        108979.043578, 110881.459251, 109537.660465],\n",
+       "       [114448.795784, 113890.2084  , 109816.770953, 107244.877409,\n",
+       "        115312.077125, 112965.096044, 109341.333989, 107943.288417,\n",
+       "        110509.904344, 105628.91408 , 106418.331646],\n",
+       "       [114010.615513, 106956.531226, 108299.370573, 110975.497546,\n",
+       "        106520.564208, 111651.127518, 101847.271629, 116306.012856,\n",
+       "        111397.074496, 109540.241678, 109143.121065],\n",
+       "       [110049.49687 , 107936.742192, 107434.442844, 115632.805702,\n",
+       "        109784.092756, 108326.291986, 107648.332703, 109537.84201 ,\n",
+       "        111955.490243, 117289.281604, 111938.231942],\n",
+       "       [109036.981589, 111276.218667, 109480.238689, 109990.723774,\n",
+       "        105906.014259, 113752.314063, 113778.474798, 114352.465532,\n",
+       "        113912.991754, 111868.071263, 111647.648043],\n",
+       "       [112503.207902, 111035.125763, 112945.937548, 108078.118731,\n",
+       "        110619.820137, 106188.445109, 106251.923299, 108532.503972,\n",
+       "        111566.93586 , 108094.394825, 114581.376521],\n",
+       "       [109996.721371, 111432.970377, 104036.708686, 107003.138241,\n",
+       "        105864.432574, 109950.195308, 112531.99177 , 111031.868949,\n",
+       "        113551.299462, 105762.103719, 109664.405794],\n",
+       "       [106083.659377, 108460.784923, 112097.037422, 104353.900532,\n",
+       "        114795.443989, 112120.590723, 108551.006769, 117160.64281 ,\n",
+       "        107194.373911, 104396.319343, 107328.274884],\n",
+       "       [107695.393415, 114701.182313, 106308.107688, 108809.212354,\n",
+       "        105610.45196 , 110577.624349, 114671.327466, 113466.805391,\n",
+       "        111480.952114, 110865.782446, 111805.614596],\n",
+       "       [114401.119537, 110566.135876, 108904.911843, 114266.230121,\n",
+       "        109680.561934, 112252.247182, 113978.043342, 113420.961902,\n",
+       "        108287.094381, 107202.135981, 103718.733094]])\n",
+       "Coordinates:\n",
+       "  * x        (x) float64 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0\n",
+       "  * y        (y) float64 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0"
+      ]
+     },
+     "execution_count": 13,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "pressure = xr.DataArray(np.random.normal(loc=1.1e5, scale=3e3, size=temperature.shape),\n",
+    "                        dims=temperature.dims, coords=temperature.coords)\n",
+    "pressure"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Arbitrary attributes can be added to an xarray to store additional metadata."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2019-07-03T08:49:48.540207Z",
+     "start_time": "2019-07-03T08:49:48.518321Z"
+    }
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "<xarray.DataArray (x: 11, y: 11)>\n",
+       "array([[109803.901687, 111194.942097, 106939.167658, 112581.874272,\n",
+       "        107370.597966, 105990.707104, 108363.976396, 108281.687394,\n",
+       "        108297.235189, 106382.832734, 112961.88931 ],\n",
+       "       [112114.749396, 108240.793539, 110317.588222, 107689.300553,\n",
+       "        107170.169005, 113727.759334, 112912.602492, 108662.417573,\n",
+       "        108979.043578, 110881.459251, 109537.660465],\n",
+       "       [114448.795784, 113890.2084  , 109816.770953, 107244.877409,\n",
+       "        115312.077125, 112965.096044, 109341.333989, 107943.288417,\n",
+       "        110509.904344, 105628.91408 , 106418.331646],\n",
+       "       [114010.615513, 106956.531226, 108299.370573, 110975.497546,\n",
+       "        106520.564208, 111651.127518, 101847.271629, 116306.012856,\n",
+       "        111397.074496, 109540.241678, 109143.121065],\n",
+       "       [110049.49687 , 107936.742192, 107434.442844, 115632.805702,\n",
+       "        109784.092756, 108326.291986, 107648.332703, 109537.84201 ,\n",
+       "        111955.490243, 117289.281604, 111938.231942],\n",
+       "       [109036.981589, 111276.218667, 109480.238689, 109990.723774,\n",
+       "        105906.014259, 113752.314063, 113778.474798, 114352.465532,\n",
+       "        113912.991754, 111868.071263, 111647.648043],\n",
+       "       [112503.207902, 111035.125763, 112945.937548, 108078.118731,\n",
+       "        110619.820137, 106188.445109, 106251.923299, 108532.503972,\n",
+       "        111566.93586 , 108094.394825, 114581.376521],\n",
+       "       [109996.721371, 111432.970377, 104036.708686, 107003.138241,\n",
+       "        105864.432574, 109950.195308, 112531.99177 , 111031.868949,\n",
+       "        113551.299462, 105762.103719, 109664.405794],\n",
+       "       [106083.659377, 108460.784923, 112097.037422, 104353.900532,\n",
+       "        114795.443989, 112120.590723, 108551.006769, 117160.64281 ,\n",
+       "        107194.373911, 104396.319343, 107328.274884],\n",
+       "       [107695.393415, 114701.182313, 106308.107688, 108809.212354,\n",
+       "        105610.45196 , 110577.624349, 114671.327466, 113466.805391,\n",
+       "        111480.952114, 110865.782446, 111805.614596],\n",
+       "       [114401.119537, 110566.135876, 108904.911843, 114266.230121,\n",
+       "        109680.561934, 112252.247182, 113978.043342, 113420.961902,\n",
+       "        108287.094381, 107202.135981, 103718.733094]])\n",
+       "Coordinates:\n",
+       "  * x        (x) float64 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0\n",
+       "  * y        (y) float64 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0\n",
+       "Attributes:\n",
+       "    units:    P\n",
+       "    source:   random data"
+      ]
+     },
+     "execution_count": 14,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "pressure.attrs['units'] = 'P'\n",
+    "pressure.attrs['source'] = 'random data'\n",
+    "pressure"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## File I/O"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "xarrays can be stored in NetCDF format, which can be used with many scientific and visualization software packages."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2019-07-03T08:49:51.697985Z",
+     "start_time": "2019-07-03T08:49:51.680769Z"
+    }
+   },
+   "outputs": [],
+   "source": [
+    "pressure.to_netcdf('pressure.nc')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2019-07-03T08:52:16.632476Z",
+     "start_time": "2019-07-03T08:52:16.482831Z"
+    }
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "pressure.nc  README.md\txarray_intro.ipynb\n"
+     ]
+    }
+   ],
+   "source": [
+    "!ls"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "To demonstrate that this is lossless, we remove the original xarray, and reinstantiate it from the NetCDF file that was saved to disk."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 17,
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2019-07-03T08:49:55.748236Z",
+     "start_time": "2019-07-03T08:49:55.734300Z"
+    }
+   },
+   "outputs": [],
+   "source": [
+    "del pressure"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 18,
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2019-07-03T08:50:20.413543Z",
+     "start_time": "2019-07-03T08:50:20.356292Z"
+    }
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "<xarray.DataArray (x: 11, y: 11)>\n",
+       "array([[109803.901687, 111194.942097, 106939.167658, 112581.874272,\n",
+       "        107370.597966, 105990.707104, 108363.976396, 108281.687394,\n",
+       "        108297.235189, 106382.832734, 112961.88931 ],\n",
+       "       [112114.749396, 108240.793539, 110317.588222, 107689.300553,\n",
+       "        107170.169005, 113727.759334, 112912.602492, 108662.417573,\n",
+       "        108979.043578, 110881.459251, 109537.660465],\n",
+       "       [114448.795784, 113890.2084  , 109816.770953, 107244.877409,\n",
+       "        115312.077125, 112965.096044, 109341.333989, 107943.288417,\n",
+       "        110509.904344, 105628.91408 , 106418.331646],\n",
+       "       [114010.615513, 106956.531226, 108299.370573, 110975.497546,\n",
+       "        106520.564208, 111651.127518, 101847.271629, 116306.012856,\n",
+       "        111397.074496, 109540.241678, 109143.121065],\n",
+       "       [110049.49687 , 107936.742192, 107434.442844, 115632.805702,\n",
+       "        109784.092756, 108326.291986, 107648.332703, 109537.84201 ,\n",
+       "        111955.490243, 117289.281604, 111938.231942],\n",
+       "       [109036.981589, 111276.218667, 109480.238689, 109990.723774,\n",
+       "        105906.014259, 113752.314063, 113778.474798, 114352.465532,\n",
+       "        113912.991754, 111868.071263, 111647.648043],\n",
+       "       [112503.207902, 111035.125763, 112945.937548, 108078.118731,\n",
+       "        110619.820137, 106188.445109, 106251.923299, 108532.503972,\n",
+       "        111566.93586 , 108094.394825, 114581.376521],\n",
+       "       [109996.721371, 111432.970377, 104036.708686, 107003.138241,\n",
+       "        105864.432574, 109950.195308, 112531.99177 , 111031.868949,\n",
+       "        113551.299462, 105762.103719, 109664.405794],\n",
+       "       [106083.659377, 108460.784923, 112097.037422, 104353.900532,\n",
+       "        114795.443989, 112120.590723, 108551.006769, 117160.64281 ,\n",
+       "        107194.373911, 104396.319343, 107328.274884],\n",
+       "       [107695.393415, 114701.182313, 106308.107688, 108809.212354,\n",
+       "        105610.45196 , 110577.624349, 114671.327466, 113466.805391,\n",
+       "        111480.952114, 110865.782446, 111805.614596],\n",
+       "       [114401.119537, 110566.135876, 108904.911843, 114266.230121,\n",
+       "        109680.561934, 112252.247182, 113978.043342, 113420.961902,\n",
+       "        108287.094381, 107202.135981, 103718.733094]])\n",
+       "Coordinates:\n",
+       "  * x        (x) float64 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0\n",
+       "  * y        (y) float64 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0\n",
+       "Attributes:\n",
+       "    units:    P\n",
+       "    source:   random data"
+      ]
+     },
+     "execution_count": 18,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "pressure = xr.open_dataarray('pressure.nc')\n",
+    "pressure"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "All metadata, including coordinates and attributes has been preserved."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Numerical computations"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Numerical operations are broadcasted along the dimensions, so to initialize a 2D array of complex numbers, we can simply initialize the real values as an xarray with dimension `re`, the imaginary values as an xarray with dimension `im`, and add the two 1D arrays to obtain a complex-valued 2D array."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 19,
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2019-07-03T05:10:07.869657Z",
+     "start_time": "2019-07-03T05:10:07.847281Z"
+    }
+   },
+   "outputs": [],
+   "source": [
+    "real_vals = xr.DataArray(np.linspace(0.0, 1.0, 11), dims='re')\n",
+    "im_vals = xr.DataArray(np.linspace(0.0j, 1.0j, 11), dims='im')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 20,
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2019-07-03T05:10:33.039569Z",
+     "start_time": "2019-07-03T05:10:32.986204Z"
+    }
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "<xarray.DataArray (re: 11, im: 11)>\n",
+       "array([[0. +0.j , 0. +0.1j, 0. +0.2j, 0. +0.3j, 0. +0.4j, 0. +0.5j, 0. +0.6j,\n",
+       "        0. +0.7j, 0. +0.8j, 0. +0.9j, 0. +1.j ],\n",
+       "       [0.1+0.j , 0.1+0.1j, 0.1+0.2j, 0.1+0.3j, 0.1+0.4j, 0.1+0.5j, 0.1+0.6j,\n",
+       "        0.1+0.7j, 0.1+0.8j, 0.1+0.9j, 0.1+1.j ],\n",
+       "       [0.2+0.j , 0.2+0.1j, 0.2+0.2j, 0.2+0.3j, 0.2+0.4j, 0.2+0.5j, 0.2+0.6j,\n",
+       "        0.2+0.7j, 0.2+0.8j, 0.2+0.9j, 0.2+1.j ],\n",
+       "       [0.3+0.j , 0.3+0.1j, 0.3+0.2j, 0.3+0.3j, 0.3+0.4j, 0.3+0.5j, 0.3+0.6j,\n",
+       "        0.3+0.7j, 0.3+0.8j, 0.3+0.9j, 0.3+1.j ],\n",
+       "       [0.4+0.j , 0.4+0.1j, 0.4+0.2j, 0.4+0.3j, 0.4+0.4j, 0.4+0.5j, 0.4+0.6j,\n",
+       "        0.4+0.7j, 0.4+0.8j, 0.4+0.9j, 0.4+1.j ],\n",
+       "       [0.5+0.j , 0.5+0.1j, 0.5+0.2j, 0.5+0.3j, 0.5+0.4j, 0.5+0.5j, 0.5+0.6j,\n",
+       "        0.5+0.7j, 0.5+0.8j, 0.5+0.9j, 0.5+1.j ],\n",
+       "       [0.6+0.j , 0.6+0.1j, 0.6+0.2j, 0.6+0.3j, 0.6+0.4j, 0.6+0.5j, 0.6+0.6j,\n",
+       "        0.6+0.7j, 0.6+0.8j, 0.6+0.9j, 0.6+1.j ],\n",
+       "       [0.7+0.j , 0.7+0.1j, 0.7+0.2j, 0.7+0.3j, 0.7+0.4j, 0.7+0.5j, 0.7+0.6j,\n",
+       "        0.7+0.7j, 0.7+0.8j, 0.7+0.9j, 0.7+1.j ],\n",
+       "       [0.8+0.j , 0.8+0.1j, 0.8+0.2j, 0.8+0.3j, 0.8+0.4j, 0.8+0.5j, 0.8+0.6j,\n",
+       "        0.8+0.7j, 0.8+0.8j, 0.8+0.9j, 0.8+1.j ],\n",
+       "       [0.9+0.j , 0.9+0.1j, 0.9+0.2j, 0.9+0.3j, 0.9+0.4j, 0.9+0.5j, 0.9+0.6j,\n",
+       "        0.9+0.7j, 0.9+0.8j, 0.9+0.9j, 0.9+1.j ],\n",
+       "       [1. +0.j , 1. +0.1j, 1. +0.2j, 1. +0.3j, 1. +0.4j, 1. +0.5j, 1. +0.6j,\n",
+       "        1. +0.7j, 1. +0.8j, 1. +0.9j, 1. +1.j ]])\n",
+       "Dimensions without coordinates: re, im"
+      ]
+     },
+     "execution_count": 20,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "vals = real_vals + im_vals\n",
+    "vals"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Although this can be done in numpy as well, it requires fiddling with extra dimensions, using xarrays this can be expressed quite naturally."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Another example is the computation and representation of volume data. A 3D Gaussian function is computed over the domain $[-3 : 3, -3 : 3, -3 : 3]$."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 21,
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2019-07-03T09:31:13.037884Z",
+     "start_time": "2019-07-03T09:31:12.962198Z"
+    }
+   },
+   "outputs": [],
+   "source": [
+    "x_coords = xr.DataArray(np.linspace(-3.0, 3.0, 101), dims='x')\n",
+    "y_coords = xr.DataArray(np.linspace(-3.0, 3.0, 101), dims='7')\n",
+    "z_coords = xr.DataArray(np.linspace(-3.0, 3.0, 101), dims='z')\n",
+    "X, Y, Z = np.meshgrid(x_coords, y_coords, z_coords)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 22,
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2019-07-03T09:32:55.971171Z",
+     "start_time": "2019-07-03T09:32:55.945115Z"
+    }
+   },
+   "outputs": [],
+   "source": [
+    "def gaussian(X, Y, Z):\n",
+    "    return np.exp(-(X**2 + Y**2 + Z**2))/np.sqrt(2.0*np.pi)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 23,
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2019-07-03T09:52:57.927742Z",
+     "start_time": "2019-07-03T09:52:57.705829Z"
+    }
+   },
+   "outputs": [],
+   "source": [
+    "values = xr.DataArray(gaussian(X, Y, Z), dims=('x', 'y', 'z'),\n",
+    "                      coords=(x_coords, y_coords, z_coords))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 24,
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2019-07-03T09:53:05.449075Z",
+     "start_time": "2019-07-03T09:53:05.438796Z"
+    }
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(101, 101, 101)"
+      ]
+     },
+     "execution_count": 24,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "values.shape"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "The data can be exported to NetCDF for visualization with, e.g., ParaView or VisIt."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 25,
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2019-07-03T09:53:57.493904Z",
+     "start_time": "2019-07-03T09:53:57.415923Z"
+    }
+   },
+   "outputs": [],
+   "source": [
+    "values.to_netcdf('gaussian.nc')"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "We can visualize two slices of the data volume, one along the $Z$-plane, the other along the $X$-plane."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 26,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<Figure size 720x360 with 2 Axes>"
+      ]
+     },
+     "metadata": {
+      "needs_background": "light"
+     },
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "figure, axes = plt.subplots(nrows=1, ncols=2, figsize=(10, 5))\n",
+    "z_slice = values.sel(z=0.0)\n",
+    "tick_locs = list(range(0, 101, 25))\n",
+    "tick_vals = np.linspace(values.coords['x'].values[0], values.coords['y'].values[-1], 5)\n",
+    "axes[0].imshow(z_slice, origin='lower', aspect='equal', cmap='coolwarm')\n",
+    "axes[0].set_title('Z slice')\n",
+    "axes[0].set_xlabel(z_slice.dims[0])\n",
+    "axes[0].set_xticks(tick_locs)\n",
+    "axes[0].set_xticklabels(f'{x:.1f}' for x in tick_vals)\n",
+    "axes[0].set_ylabel(z_slice.dims[1])\n",
+    "axes[0].set_yticks(tick_locs)\n",
+    "axes[0].set_yticklabels(f'{x:.1f}' for x in tick_vals)\n",
+    "x_slice = values.sel(x=0.0)\n",
+    "axes[1].imshow(x_slice, origin='lower', aspect='equal', cmap='coolwarm')\n",
+    "axes[1].set_title('X slice')\n",
+    "axes[1].set_xlabel(x_slice.dims[0])\n",
+    "axes[1].set_xticks(tick_locs)\n",
+    "axes[1].set_xticklabels(f'{x:.1f}' for x in tick_vals)\n",
+    "axes[1].set_ylabel(x_slice.dims[1])\n",
+    "axes[1].set_yticks(tick_locs)\n",
+    "axes[1].set_yticklabels(f'{x:.1f}' for x in tick_vals)\n",
+    "plt.tight_layout()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Note that labels and tick values are set according to information contained in the xarray representing the data."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Interpolation"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "It is straightforward to interpolate data for coordinates that are missing in the xarray, e.g.,"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 27,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "0.0002448162927385368"
+      ]
+     },
+     "execution_count": 27,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "float(values.interp(x=np.pi/2.0, y=np.pi/2.0, z=np.pi/2.0))"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "The interpolation is linear, and this function is highly non-linear, so the actual function values at the given point is different."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 28,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "0.00024331787691818835"
+      ]
+     },
+     "execution_count": 28,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "gaussian(np.pi/2.0, np.pi/2.0, np.pi/2.0)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Interpolation can be done for an entire plane of 3D data."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 29,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "<xarray.DataArray (y: 101, z: 101)>\n",
+       "array([[2.497462e-11, 3.566822e-11, 5.057514e-11, ..., 5.057514e-11,\n",
+       "        3.566822e-11, 2.497462e-11],\n",
+       "       [3.566822e-11, 5.094060e-11, 7.223034e-11, ..., 7.223034e-11,\n",
+       "        5.094060e-11, 3.566822e-11],\n",
+       "       [5.057514e-11, 7.223034e-11, 1.024178e-10, ..., 1.024178e-10,\n",
+       "        7.223034e-11, 5.057514e-11],\n",
+       "       ...,\n",
+       "       [5.057514e-11, 7.223034e-11, 1.024178e-10, ..., 1.024178e-10,\n",
+       "        7.223034e-11, 5.057514e-11],\n",
+       "       [3.566822e-11, 5.094060e-11, 7.223034e-11, ..., 7.223034e-11,\n",
+       "        5.094060e-11, 3.566822e-11],\n",
+       "       [2.497462e-11, 3.566822e-11, 5.057514e-11, ..., 5.057514e-11,\n",
+       "        3.566822e-11, 2.497462e-11]])\n",
+       "Coordinates:\n",
+       "  * y        (y) float64 -3.0 -2.94 -2.88 -2.82 -2.76 ... 2.82 2.88 2.94 3.0\n",
+       "  * z        (z) float64 -3.0 -2.94 -2.88 -2.82 -2.76 ... 2.82 2.88 2.94 3.0\n",
+       "    x        float64 2.344"
+      ]
+     },
+     "execution_count": 29,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "values.interp(x=np.pi/1.34)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "toc-hr-collapsed": true
+   },
+   "source": [
+    "## Combining data"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Concatenate"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "The `cnocatinate` function works similarly to what you would expect from numpy's counterpart. Two or more `DataArray`s are concatenated as in the following example."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 30,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "x_vals = np.arange(0.0, 2.0*np.pi, 0.3)\n",
+    "signal1 = xr.DataArray(np.cos(x_vals), dims=('x', ), coords=(x_vals.copy(), ))\n",
+    "x_vals += 5.0*np.pi\n",
+    "signal2 = xr.DataArray(np.cos(x_vals), dims=('x', ), coords=(x_vals.copy(), ))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 31,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "signal = xr.concat((signal1, signal2), dim='x')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 32,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[<matplotlib.lines.Line2D at 0x7fef401cfda0>]"
+      ]
+     },
+     "execution_count": 32,
+     "metadata": {},
+     "output_type": "execute_result"
+    },
+    {
+     "data": {
+      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYIAAAEGCAYAAABo25JHAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjAsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+17YcXAAAZpUlEQVR4nO3df7Bc5X3f8ffH4pdap5VkXVwhJEukGmwSd6RkjTNRJ7UJGNmdQYrjH8LjWM7gUdsxTX9FE9F04g6xa7meFNKWplEwQU4dMCa2UMbOKCDhujMJqVaRjCQolSITuPdq4NpCSWdQAIlv/9hz8Wq1e+/ePefuOWefz2tmZ/c855zdR4fL+Z7nPM/zPYoIzMwsXW8quwJmZlYuBwIzs8Q5EJiZJc6BwMwscQ4EZmaJu6TsCgxi6dKlsWrVqrKrYWZWKwcPHvx+RIx1ltcyEKxatYpms1l2NczMakXSX3Yr960hM7PEORCYmSXOgcDMLHEOBGZmiXMgMDNLXCGBQNJ9kl6UdLTHekn6z5JOSHpS0k+0rdsi6Xj22lJEfbrZfWiC9Tv2s3r7N1m/Yz+7D03M10+ZmdVKUcNH7wf+K/DlHuvfD6zJXu8Gfgt4t6QlwGeABhDAQUl7IuKlguoFtILAHV8/wtnXzgMwceYsd3z9CACb1i0v8qfMrEZ2H5rgi3ufYfLMWa5atJBtN18LcFHZqJ8nCgkEEfEdSatm2GQj8OVo5bx+QtIiScuA9wCPRsRpAEmPAhuAB4qo17Qv7n3mjSAw7exr5/ni3mdG/j+wmXXX7QJx29e+C4LXzscbZSlcNA6rj2A58Hzb8nhW1qv8IpK2SmpKak5NTc3pxyfPnJ1TuZmNvm4XiK+9Hm8EgWnTF42jbFgzi9WlLGYov7gwYiewE6DRaMzpaTpXLVrIRJeT/lWLFs7la6xNtyb1KF8x2eiZy4XgqF80DqtFMA6saFu+GpicobxQ226+loWXLrig7NI3iZdfPefO4wFMN6knzpwl+GHz2cfQ6mQuF4KjftE4rECwB/hENnrop4C/iohTwF7gfZIWS1oMvC8rK9Smdcv5/AffyfJFCxGwaOGlIHjp5dd8IhvATH0uZnXR6wLx0gUX3qhYeOmCNzqRR1Uht4YkPUCr43eppHFaI4EuBYiI/w58C/gAcAJ4GfjFbN1pSb8OHMi+6s7pjuOibVq3/I1bF+t37OfM2dcuWO/O4/65z8VGwfT/6x41VNyooVtnWR/Ap3usuw+4r4h69Msnsnzc52Kjov0CsbM8JUnOLO51wvKJrD/dmtQpNJ/NRlUtn0eQ17abr71g/DD4RDYXvZrUqV1FWf0MMtothRFySQYCn8jy69WkNquqQTIMpJKVIMlAAD6RmaVmkAwDqWQlSLKPwMzSM8ggkVQGljgQmFkSBhkkksrAEgcCM0vCIKPdUhkhl2wfgZmlZZBBIqkMLFFrrle9NBqNaDabZVcjKSkMoTMbdZIORkSjs9wtgoxPdL2lMoTOLFXuI8DZNGfjJHNmo82BAJ/oZpPKEDqzVDkQ4BPdbFIZQmeWKgcCfKKbTSpD6MxS5UCAT3Sz6Xywz/JFC/n8B9/pjmKzEeFRQ6QzVjgP52YyG11FPaFsA/CbwALg3ojY0bH+LuC92eLfAq6MiEXZuvPAkWzdcxFxSxF1miuf6MwsVbkDgaQFwD3ATbQeRn9A0p6IeGp6m4j4V23b/3NgXdtXnI2ItXnrYWbWyfOD+lNEi+B64EREnASQ9CCwEXiqx/a30nqmsZnZvJmviZCjGFyK6CxeDjzftjyelV1E0tuA1cD+tuIrJDUlPSFpU68fkbQ12645NTVVQLXNbJTNx/ygUZ18WkQgUJeyXgmMNgMPR0T7f52VWe6LjwF3S/rRbjtGxM6IaEREY2xsLF+NzWzkzcf8oFGdfFpEIBgHVrQtXw1M9th2M/BAe0FETGbvJ4Fvc2H/gZnZQOZjftCoTj4tIhAcANZIWi3pMlon+z2dG0m6FlgM/Glb2WJJl2eflwLr6d23YGbWt/mYHzSqk09zB4KIOAfcDuwFngYeiohjku6U1D4U9Fbgwbgw7/U7gKak7wKPAzvaRxuZmQ1qPiZCjurkUz+PwMxsDuo8asjPIzAzK8AoTj51riEzs8S5RWBd1bn5a2Zz40BgF/GjKc3S4kAwg1SvimeaNJPCv98sNQ4EPaR8VTyqk2bMrDt3FvcwqlPJ+zGqk2bMrDsHgh5Svioe1UkzZtadA0EPKV8V+9GUZmlxH0EP226+9oI+AkjrqngUJ82YWXcOBD34OcZmlgoHghn4qtjMUuA+AjOzxDkQmJklzoHAzCxx7iMws5GRalqYvAppEUjaIOkZSSckbe+y/pOSpiQdzl6falu3RdLx7LWliPqYWXqm08JMnDlL8MO0MLsPTZRdtcrL3SKQtAC4B7iJ1oPsD0ja0+WRk1+NiNs79l0CfAZoAAEczPZ9KW+9zCwtZSVLHIVWSBEtguuBExFxMiJeBR4ENva5783AoxFxOjv5PwpsKKBOZpaYMtLCjEorpIhAsBx4vm15PCvr9POSnpT0sKQVc9wXSVslNSU1p6amCqi2mY2SMtLCjEpyyiICgbqURcfyHwKrIuIfAI8Bu+awb6swYmdENCKiMTY2NnBlzWw0lZEscVSSUxYRCMaBFW3LVwOT7RtExA8i4pVs8XeAn+x3XzOzfpSRLHFUklMWMXz0ALBG0mpgAtgMfKx9A0nLIuJUtngL8HT2eS/wHyQtzpbfB9xRQJ3MLEHDTgszKskpcweCiDgn6XZaJ/UFwH0RcUzSnUAzIvYAvyTpFuAccBr4ZLbvaUm/TiuYANwZEafz1snMbBhGJTmlIrrekq+0RqMRzWaz7GqYmdWKpIMR0egsd4oJM7PEORCYmSXOgcDMLHFOOmfAaEyTN7PBOBDMwaieLKenyU8PgZueJg+MxL/PzGbmW0N9GpWcIt2MyjR5MxuMA0GfRvlkOSrT5M1sMA4EfRrlk+WoTJM3s8E4EPRplE+WZSTrMrPqcCDo0yifLMtI1mVm1eFRQ30alZwivQw7WZeZVYcDwRz4ZGlmo8i3hszMEudAYGaWOAcCM7PEFRIIJG2Q9IykE5K2d1n/ryU9lT28fp+kt7WtOy/pcPbaU0R9zMysf7k7iyUtAO4BbqL1DOIDkvZExFNtmx0CGhHxsqR/BvxH4KPZurMRsTZvPczMbDBFtAiuB05ExMmIeBV4ENjYvkFEPB4RL2eLT9B6SL2ZmVVAEcNHlwPPty2PA++eYfvbgD9qW75CUpPW84x3RMTubjtJ2gpsBVi5cmWuCpvZaBjVjMDDVkQgUJeyrg9ClvRxoAH8o7bilRExKekaYL+kIxHxFxd9YcROYCe0nlmcv9pmVmdVTZ9ex+BUxK2hcWBF2/LVwGTnRpJuBH4VuCUiXpkuj4jJ7P0k8G1gXQF1MrMRV8WMwHVNV19EIDgArJG0WtJlwGbggtE/ktYBv00rCLzYVr5Y0uXZ56XAeqC9k9nMrKsqZgSuYnDqR+5AEBHngNuBvcDTwEMRcUzSnZJuyTb7IvBm4Gsdw0TfATQlfRd4nFYfgQOBmc2qihmBqxic+lFIrqGI+BbwrY6yX2v7fGOP/f4EeGcRdTCztGy7+doL+gig/IzAVy1ayESXk37V09V7ZrGZ1VIV06fXNV29s4+aWW1VLSNwXdPVOxCYmRWoasGpH741ZGaWOAcCM7PEORCYmSXOgcDMLHHuLE5QHXOhmNn8cSBITFUTdZlZeRwIcqjjlfVMuVCqXnczmx8OBAOq65V1XXOhmNn8cWfxgOqaZbCKibrMrFwOBAOq65V1XXOhmNn8cSAYUF2vrKuYqMvMyuU+ggFVMQVuv+qYC8XM5o8DwYDqmmXQzKxTIYFA0gbgN4EFwL0RsaNj/eXAl4GfBH4AfDQins3W3QHcBpwHfiki9hZRp2HwlbWZjYLcfQSSFgD3AO8HrgNulXRdx2a3AS9FxN8H7gK+kO17Ha1nHP8YsAH4b9n3mZnZkBTRWXw9cCIiTkbEq8CDwMaObTYCu7LPDwM/K0lZ+YMR8UpEfA84kX2fmZkNSRGBYDnwfNvyeFbWdZvsYfd/Bbylz30BkLRVUlNSc2pqqoBqm5kZFBMI1KUs+tymn31bhRE7I6IREY2xsbE5VtHMzHopIhCMAyvalq8GJnttI+kS4O8Cp/vc18zM5lERgeAAsEbSakmX0er83dOxzR5gS/b5Q8D+iIisfLOkyyWtBtYA/7uAOpmZWZ9yDx+NiHOSbgf20ho+el9EHJN0J9CMiD3Al4Dfk3SCVktgc7bvMUkPAU8B54BPR8T5rj9kZkmrY7bfulDrwrxeGo1GNJvNsqthZkPSme0XWjP5nR5lbiQdjIhGZ7lnFptZ5dX9ORpVb804EJhZ5dU12y/U49klzj5qZpVX12y/UI9nlzgQmFnl1fk5GnVozTgQmFnl1fk5GnVozbiPwMxqoa7Zfuvw7BIHAjOzeVSHZ5c4EJiZzbOqt2bcR2BmljgHAjOzxDkQmJklzoHAzCxx7ixOQNXznJhZuRwIRlwd8pyYWbkcCApUxSvvumdtNLP550BQkKpeedchz4mZlStXZ7GkJZIelXQ8e1/cZZu1kv5U0jFJT0r6aNu6+yV9T9Lh7LU2T33KVNUMg3XIc2Jm5co7amg7sC8i1gD7suVOLwOfiIgfAzYAd0ta1LZ+W0SszV6Hc9anNFW98q5z1kYzG468gWAjsCv7vAvY1LlBRPzfiDiefZ4EXgTGcv5u5VT1yrvOWRvNbDjy9hG8NSJOAUTEKUlXzrSxpOuBy4C/aCv+nKRfI2tRRMQrPfbdCmwFWLlyZc5qF6/KGQarnufEzMo1a4tA0mOSjnZ5bZzLD0laBvwe8IsR8XpWfAfwduBdwBLgV3rtHxE7I6IREY2xseo1KHzlbWZ1NWuLICJu7LVO0guSlmWtgWW0bvt02+7vAN8E/l1EPNH23aeyj69I+l3gl+dU+4rxlbeZ1VHePoI9wJbs8xbgkc4NJF0GfAP4ckR8rWPdsuxdtPoXjuasj5mZzVHeQLADuEnSceCmbBlJDUn3Ztt8BPgZ4JNdhol+RdIR4AiwFPhszvqYmdkcKSLKrsOcNRqNaDabZVfDzKxWJB2MiEZnubOPmpklzoHAzCxxzjVkZpVUxSSOo8qBwMwqp6pJHItStSDnW0NmVjlVTeJYhOkgN3HmLMEPg9zuQxOl1cmBwMwqp6pJHItQxSDnQGBmlVPVJI5FqGKQcyAws8oZ5fTpVQxyDgRmVjmjnMSxikHOo4bMrJJGNYnj9L+pSqOGHAjMzIasakHOt4bMzBLnQGBmljgHAjOzxDkQmJklLldnsaQlwFeBVcCzwEci4qUu252n9fAZgOci4pasfDXwIK3nFf858AsR8WqeOln18piYWbXlbRFsB/ZFxBpgX7bczdmIWJu9bmkr/wJwV7b/S8BtOetTKbsPTbB+x35Wb/8m63fsH0oukSrmMTGzassbCDYCu7LPu2g9d7gv2XOKbwAeHmT/qivrhFzFPCZmVm15A8FbI+IUQPZ+ZY/trpDUlPSEpOmT/VuAMxFxLlseB3rev5C0NfuO5tTUVM5qz7+yTshVzGNiZtU2ax+BpMeAv9dl1a/O4XdWRsSkpGuA/dkD6/+6y3Y9H6AcETuBndB6ZvEcfrsUZZ2Qr1q0kIkuvzEKybrMbH7M2iKIiBsj4se7vB4BXpC0DCB7f7HHd0xm7yeBbwPrgO8DiyRNB6Orgcnc/6KKKCuxVBXzmJhZteW9NbQH2JJ93gI80rmBpMWSLs8+LwXWA09FRACPAx+aaf+6KuuEPMrJusxsfqh1Ph5wZ+ktwEPASuA54MMRcVpSA/inEfEpST8N/DbwOq3Ac3dEfCnb/xp+OHz0EPDxiHhltt9tNBrRbDYHrveweBinmVWJpIMR0bioPE8gKEtdAoGZWZX0CgSeWWxmljgHAjOzxDkQmJklzoHAzCxxfkKZmVWCR9mVx4HAzEo3nZtrOi3LdG4uIIlgUHYQ9K0hMytdyskSq5Ax2IHAzEqXcrLEKgRBBwIzK11ZubmqoApB0IHAzEqXcrLEKgRBBwIzK13KyRKrEAQ9asjMKmHTuuVJnPg7Tf+byxw15EBgZlaysoOgbw2ZmSXOLYIRUPZkFDOrNweCISv6pJ36jEwzyy/XrSFJSyQ9Kul49r64yzbvlXS47fU3kjZl6+6X9L22dWvz1Kfq5mMGYRUmo5hZveXtI9gO7IuINcC+bPkCEfF4RKyNiLXADcDLwB+3bbJten1EHM5Zn0qbj5N2FSajmFm95Q0EG4Fd2eddwKZZtv8Q8EcR8XLO362l+ThpV2EyipnVW95A8NaIOAWQvV85y/abgQc6yj4n6UlJd0m6vNeOkrZKakpqTk1N5at1SebjpF2FyShmVm+zBgJJj0k62uW1cS4/JGkZ8E5gb1vxHcDbgXcBS4Bf6bV/ROyMiEZENMbGxuby05UxHyftlGdkmlkxZh01FBE39lon6QVJyyLiVHaif3GGr/oI8I2IeK3tu09lH1+R9LvAL/dZ71qarxmEZU9GMbN6yzt8dA+wBdiRvT8yw7a30moBvKEtiIhW/8LRnPWpPJ+0zaxq8vYR7ABuknQcuClbRlJD0r3TG0laBawA/mfH/l+RdAQ4AiwFPpuzPmZmNke5WgQR8QPgZ7uUN4FPtS0/C1x0GRwRN+T5fTOrL8+Irw7PLDazofOM+JkNO0g66ZyZDZ1nxPdWxjOMHQjMbOg8I763MoKkA4GZDZ1nxPdWRpB0IDCzofOM+N7KCJIOBGY2dJ4R31sZQdKjhko2yOgAD7uzUeDJld2V8QxjB4ISDTKEzsPuzEbfsIOkbw2VaJDRAR52Z2ZFcyAo0SCjAzzszsyK5kBQokFGB3jYnZkVzYGgRIOMDvCwOzMrmjuLSzTI6IAyRhSY5eWRbvnM9/FTRBT2ZcPSaDSi2WyWXQ0z60PnSDdotWI9b6A/RR4/SQcjotFZ7ltDZjavPNItn2EcP98aqpjOJuB73z7G4/9nyk1qqy2PdMtnGMcvV4tA0oclHZP0uqSLmhtt222Q9IykE5K2t5WvlvRnko5L+qqky/LUp+66pZ/9H088N9R0tGZF2H1ogvU79rN6+zd5k9R1G490688wRgrmvTV0FPgg8J1eG0haANwDvB+4DrhV0nXZ6i8Ad0XEGuAl4Lac9am1bk3ATm5SW9V1XtCc79IP6ZFu/RvGSMFcgSAino6I2c5K1wMnIuJkRLwKPAhszB5YfwPwcLbdLloPsE9Wv009N6mtynpd0CyQnGBuAMNI0DeMPoLlwPNty+PAu4G3AGci4lxbec9/maStwFaAlStXzk9NS3bVooVM9HGSd5PaqqzXhcrrEXxvxz8ecm1Gw3znHpq1RSDpMUlHu7w29vkb3W4QxgzlXUXEzohoRERjbGysz5+ul25NwE5uUlvVefZ7/czaIoiIG3P+xjiwom35amAS+D6wSNIlWatgujxZ3SaLedSQ1c22m6/tOu7dFzDVNYxbQweANZJWAxPAZuBjERGSHgc+RKvfYAvwyBDqU2nO0W5159nv9ZNrZrGknwP+CzAGnAEOR8TNkq4C7o2ID2TbfQC4G1gA3BcRn8vKr6EVBJYAh4CPR8Qrs/2uZxabmc1dr5nFTjFhZpYIp5gwM7OuHAjMzBLnQGBmljgHAjOzxNWys1jSFPCXA+6+lNYcBruQj0t3Pi7d+bh0V/Xj8raIuGhGbi0DQR6Smt16zVPn49Kdj0t3Pi7d1fW4+NaQmVniHAjMzBKXYiDYWXYFKsrHpTsfl+58XLqr5XFJro/AzMwulGKLwMzM2jgQmJklLqlAIGmDpGcknZC0vez6VIWkZyUdkXRYUrLZ/CTdJ+lFSUfbypZIelTS8ex9cZl1LEOP4/LvJU1kfzOHswzDSZG0QtLjkp6WdEzSv8jKa/c3k0wgkLQAuAd4P3AdcKuk68qtVaW8NyLW1nEMdIHuBzZ0lG0H9kXEGmBftpya+7n4uADclf3NrI2Ibw25TlVwDvg3EfEO4KeAT2fnlNr9zSQTCIDrgRMRcTIiXqX1HIR+H7dpCYiI7wCnO4o3Aruyz7uATUOtVAX0OC7Ji4hTEfHn2ef/BzxN67nrtfubSSkQLAeeb1sez8qs9azoP5Z0UNLWsitTMW+NiFPQ+h8fuLLk+lTJ7ZKezG4dVf72x3yStApYB/wZNfybSSkQqEuZx862rI+In6B12+zTkn6m7ApZ5f0W8KPAWuAU8BvlVqc8kt4M/AHwLyPir8uuzyBSCgTjwIq25auByZLqUikRMZm9vwh8g9ZtNGt5QdIygOz9xZLrUwkR8UJEnI+I14HfIdG/GUmX0goCX4mIr2fFtfubSSkQHADWSFot6TJgM7Cn5DqVTtLflvQj05+B9wFHZ94rKXuALdnnLcAjJdalMqZPdJmfI8G/GUkCvgQ8HRH/qW1V7f5mkppZnA1xuxtYANwXEZ8ruUqlk3QNrVYAwCXA76d6XCQ9ALyHVirhF4DPALuBh4CVwHPAhyMiqY7THsflPbRuCwXwLPBPpu+Lp0LSPwT+F3AEeD0r/re0+glq9TeTVCAwM7OLpXRryMzMunAgMDNLnAOBmVniHAjMzBLnQGBmljgHAjOzxDkQmJklzoHArACS3pUlYLsim619TNKPl10vs354QplZQSR9FrgCWAiMR8TnS66SWV8cCMwKkuWwOgD8DfDTEXG+5CqZ9cW3hsyKswR4M/AjtFoGZrXgFoFZQSTtofXku9XAsoi4veQqmfXlkrIrYDYKJH0COBcRv589H/tPJN0QEfvLrpvZbNwiMDNLnPsIzMwS50BgZpY4BwIzs8Q5EJiZJc6BwMwscQ4EZmaJcyAwM0vc/wf4+Zbbp78QWQAAAABJRU5ErkJggg==\n",
+      "text/plain": [
+       "<Figure size 432x288 with 1 Axes>"
+      ]
+     },
+     "metadata": {
+      "needs_background": "light"
+     },
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "signal.plot.line('o')"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "However, the coordinates of the `DataArray`s can overlap, as the next example illustrates."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 33,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "x_vals = np.linspace(0.0, 2.0*np.pi, 11)\n",
+    "signal1 = xr.DataArray(np.sin(x_vals), dims=('x', ), coords=(x_vals.copy(), ))\n",
+    "x_vals = np.linspace(0.0, np.pi, 20)\n",
+    "signal2 = xr.DataArray(np.sin(x_vals), dims=('x', ), coords=(x_vals.copy(), ))\n",
+    "signal = xr.concat((signal1, signal2), dim='x')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 34,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<Figure size 432x288 with 1 Axes>"
+      ]
+     },
+     "metadata": {
+      "needs_background": "light"
+     },
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "figure, axes = plt.subplots(nrows=1, ncols=1)\n",
+    "_ = signal.plot.line('bo', ax=axes, alpha=0.5)\n",
+    "_ = signal.plot.line('ro', ax=axes, alpha=0.5)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### `merge`"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Two (or more) `DataArray` objects can be merged into a single `DataSet` object.  The coordinates are taken into account, and if one of the arrays has no values for the some coordinates, those are considered missing values, and represented as `NaN`.\n",
+    "\n",
+    "Consider two `DataArray`s, one representing temperature measurements, the other pressure values.  Both data sets have $x$ and $y$ dimensions, but the coordinates differ."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 35,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "temperature = xr.DataArray(np.random.normal(loc=20.0, scale=5.0, size=(5, 5)),\n",
+    "                           dims=('x', 'y'), coords={'x': np.linspace(0.0, 1.0, 5),\n",
+    "                                                    'y': np.linspace(0.0, 5.0, 5)},\n",
+    "                           name='temperature')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 36,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "pressure = xr.DataArray(np.random.normal(loc=1001.0, scale=100.0, size=(5, 5)),\n",
+    "                        dims=('x', 'y'), coords={'x': np.linspace(0.0, 2.0, 5),\n",
+    "                                                 'y': np.linspace(0.0, 3.0, 5)},\n",
+    "                        name='pressure')"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "When the data is merged into a `DataSet`, missing values are present."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 37,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "<xarray.Dataset>\n",
+       "Dimensions:      (x: 7, y: 9)\n",
+       "Coordinates:\n",
+       "  * x            (x) float64 0.0 0.25 0.5 0.75 1.0 1.5 2.0\n",
+       "  * y            (y) float64 0.0 0.75 1.25 1.5 2.25 2.5 3.0 3.75 5.0\n",
+       "Data variables:\n",
+       "    temperature  (x, y) float64 12.85 nan 17.28 nan nan ... nan nan nan nan nan\n",
+       "    pressure     (x, y) float64 980.1 1.049e+03 nan 887.3 ... nan 863.6 nan nan"
+      ]
+     },
+     "execution_count": 37,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "data = xr.merge((temperature, pressure))\n",
+    "data"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "We can visualize the missing data which shows up as yellow in the plot below."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 38,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<Figure size 720x360 with 2 Axes>"
+      ]
+     },
+     "metadata": {
+      "needs_background": "light"
+     },
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "figure, axes = plt.subplots(nrows=1, ncols=2, figsize=(10, 5))\n",
+    "missing_temp = np.where(np.isnan(data['temperature']), 1, 0)\n",
+    "_ = axes[0].imshow(missing_temp)\n",
+    "missing_pressure = np.where(np.isnan(data['pressure']), 1, 0)\n",
+    "_ = axes[1].imshow(missing_pressure)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### `combine_first`"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "This operation combines values from two `DataArrays`, using the second to fill holes in the first.  Coordinates for which there is no data in either `DataArray` will be filled with `NaN`."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 39,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "temp1 = xr.DataArray(np.random.normal(loc=20.0, scale=5.0, size=(5, 5)),\n",
+    "                     dims=('x', 'y'), coords={'x': np.linspace(0.0, 1.0, 5),\n",
+    "                                              'y': np.linspace(0.0, 5.0, 5)},\n",
+    "                     name='temperature')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 40,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "20.11382655394448"
+      ]
+     },
+     "execution_count": 40,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "float(temp1[0, 0])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 41,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "temp2 = xr.DataArray(np.random.normal(loc=1001.0, scale=100.0, size=(5, 5)),\n",
+    "                     dims=('x', 'y'), coords={'x': np.linspace(0.0, 2.0, 5),\n",
+    "                                              'y': np.linspace(0.0, 3.0, 5)},\n",
+    "                     name='temperature2')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 42,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "984.5785416251795"
+      ]
+     },
+     "execution_count": 42,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "float(temp2[0, 0])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 43,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "<xarray.DataArray 'temperature' (x: 7, y: 9)>\n",
+       "array([[  20.113827,  888.497042,   12.389981,  906.87979 ,  937.256577,\n",
+       "          19.466302, 1033.671747,   18.583193,   18.753926],\n",
+       "       [  22.202359,         nan,   20.25111 ,         nan,         nan,\n",
+       "          16.085346,         nan,   21.505438,   18.16582 ],\n",
+       "       [  23.535183,  979.444057,   15.905364,  940.70527 ,  894.669516,\n",
+       "          18.419255,  994.226217,   21.9216  ,   14.94299 ],\n",
+       "       [  11.313709,         nan,   19.651778,         nan,         nan,\n",
+       "          23.090102,         nan,   19.915249,   22.408933],\n",
+       "       [  16.060364, 1058.513252,   22.143258, 1004.384872, 1180.707694,\n",
+       "          21.97311 , 1143.701222,   19.243541,   19.496173],\n",
+       "       [1156.223497,  961.185423,         nan, 1137.545283, 1009.455177,\n",
+       "                nan,  979.820387,         nan,         nan],\n",
+       "       [1079.365076,  948.521418,         nan, 1036.317489, 1082.974639,\n",
+       "                nan,  982.139687,         nan,         nan]])\n",
+       "Coordinates:\n",
+       "  * x        (x) float64 0.0 0.25 0.5 0.75 1.0 1.5 2.0\n",
+       "  * y        (y) float64 0.0 0.75 1.25 1.5 2.25 2.5 3.0 3.75 5.0"
+      ]
+     },
+     "execution_count": 43,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "data = temp1.combine_first(temp2)\n",
+    "data"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "We can visualize the origin of the data, either `temp1` in blue or `temp2` in red, as well as the missing data which shows up in white."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 44,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<Figure size 432x288 with 1 Axes>"
+      ]
+     },
+     "metadata": {
+      "needs_background": "light"
+     },
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "data_map = np.empty(data.shape)\n",
+    "with np.errstate(invalid='ignore'):\n",
+    "    data_map[data.values < 200.0] = -1.0\n",
+    "    data_map[data.values >= 200.0] = 1.0\n",
+    "data_map[np.isnan(data.values)] = 0.0\n",
+    "_ = plt.imshow(data_map, cmap='bwr')"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "The plot below illustrates that the `combine_first` operator is not symmetric, i.e., `temp1.combine_first(temp2)` is not the same `DataArray` as `temp2.combine_first(temp1)`."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 45,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<Figure size 432x288 with 1 Axes>"
+      ]
+     },
+     "metadata": {
+      "needs_background": "light"
+     },
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "data = temp2.combine_first(temp1)\n",
+    "data_map = np.empty(data.shape)\n",
+    "with np.errstate(invalid='ignore'):\n",
+    "    data_map[data.values < 200.0] = -1.0\n",
+    "    data_map[data.values >= 200.0] = 1.0\n",
+    "data_map[np.isnan(data.values)] = 0.0\n",
+    "_ = plt.imshow(data_map, cmap='bwr')"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "As a second example, `combine_first` can also be used to concatenate two 1D `DataArray`'s. Data along the same dimension can be combined from several xarrays. Consider a sinusoidal signal."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 46,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(15,)"
+      ]
+     },
+     "execution_count": 46,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "x_vals = np.linspace(0.0, 2.0*np.pi, 15)\n",
+    "signal = xr.DataArray(np.sin(x_vals), dims=('x',), coords=(x_vals,), name='signal')\n",
+    "signal.shape"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 47,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<Figure size 432x288 with 1 Axes>"
+      ]
+     },
+     "metadata": {
+      "needs_background": "light"
+     },
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "_ = signal.plot.line('o')"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Create a second xarray by interpolating the signal.  Since this is 1D data, we can use quadratic interpolation, which is obviously better than the default, linear."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 48,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(62,)"
+      ]
+     },
+     "execution_count": 48,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "x_vals = np.arange(0.1, 2.0*np.pi, 0.1)\n",
+    "interp_signal = signal.interp(x=x_vals, method='quadratic')\n",
+    "interp_signal.shape"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 49,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "<xarray.DataArray 'signal' (x: 62)>\n",
+       "array([ 0.103189,  0.202644,  0.298364,  0.390351,  0.478603,  0.563122,\n",
+       "        0.643753,  0.717532,  0.783318,  0.841111,  0.890911,  0.932165,\n",
+       "        0.963651,  0.985326,  0.997191,  0.999242,  0.991466,  0.973857,\n",
+       "        0.946414,  0.909138,  0.86266 ,  0.808261,  0.74598 ,  0.675816,\n",
+       "        0.597944,  0.514878,  0.427436,  0.33562 ,  0.239428,  0.140362,\n",
+       "        0.041231, -0.0579  , -0.157031, -0.255909, -0.351364, -0.442445,\n",
+       "       -0.529151, -0.611482, -0.688165, -0.757003, -0.817959, -0.871033,\n",
+       "       -0.916094, -0.951717, -0.977506, -0.993462, -0.999584, -0.995882,\n",
+       "       -0.982368, -0.959043, -0.925907, -0.883096, -0.831952, -0.772815,\n",
+       "       -0.705685, -0.630562, -0.549171, -0.464025, -0.375145, -0.28253 ,\n",
+       "       -0.186182, -0.086099])\n",
+       "Coordinates:\n",
+       "  * x        (x) float64 0.1 0.2 0.3 0.4 0.5 0.6 0.7 ... 5.7 5.8 5.9 6.0 6.1 6.2"
+      ]
+     },
+     "execution_count": 49,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "interp_signal"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 50,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<Figure size 432x288 with 1 Axes>"
+      ]
+     },
+     "metadata": {
+      "needs_background": "light"
+     },
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "figure, axes = plt.subplots(nrows=1, ncols=1)\n",
+    "_ = signal.plot.line('r-o', ax=axes)\n",
+    "_ = interp_signal.plot.line('b.', ax=axes)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Combine the original and the interpolated signal into a single xarray."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 51,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(77,)"
+      ]
+     },
+     "execution_count": 51,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "combined = signal.combine_first(interp_signal)\n",
+    "combined.shape"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 52,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<Figure size 432x288 with 1 Axes>"
+      ]
+     },
+     "metadata": {
+      "needs_background": "light"
+     },
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "_ = combined.plot.line('.')"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Split-apply-combine: grouping"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "As in pandas, data in `DataArray`s can be grouped using the `group_by` method.  It is mostly done for data with categorical coordinates, and works similar to its pandas counterpart.  However, xarray has the `groupby_bins` method that is very convenient."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 53,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "coords = np.arange(0.0, 20.0, 1.0)\n",
+    "temperature = xr.DataArray(np.random.normal(loc=20.0, scale=2.0, size=(coords.shape[0], coords.shape[0])),\n",
+    "                           dims=('x', 'y'), coords={'x': coords, 'y': coords}, name='temperature')"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "The data may be grouped by $x$ coordinates, e.g., into 5 bins."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 54,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "bins = np.arange(-0.1, 20.1, 4.0)\n",
+    "labels = np.arange(2.0, 19.0, 4.0)\n",
+    "x_groups = temperature.groupby_bins('x', bins, labels=labels)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "As labels for the bins, the midpoint of the bin intervals is chosen.  The resulting groups show that each of the five groups contains 4 indices along the $x$-axis."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 55,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{2.0: [0, 1, 2, 3],\n",
+       " 6.0: [4, 5, 6, 7],\n",
+       " 10.0: [8, 9, 10, 11],\n",
+       " 14.0: [12, 13, 14, 15],\n",
+       " 18.0: [16, 17, 18, 19]}"
+      ]
+     },
+     "execution_count": 55,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "x_groups.groups"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "For each of these groups, we can print the label, the group's shape, and the average over the group."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 56,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "2.0 (4, 20): 19.817438\n",
+      "6.0 (4, 20): 20.180375\n",
+      "10.0 (4, 20): 20.153093\n",
+      "14.0 (4, 20): 19.921520\n",
+      "18.0 (4, 20): 20.003914\n"
+     ]
+    }
+   ],
+   "source": [
+    "for label, group in x_groups:\n",
+    "    print(f'{label} {group.shape}: {float(group.mean()):.6f}')"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Using the `apply` method on a group-by object will perform the same computation, but combine the results back into a `DataArray` with the appropriate coordinates."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 57,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "<xarray.DataArray 'temperature' (x: 5)>\n",
+       "array([19.817438, 20.180375, 20.153093, 19.92152 , 20.003914])\n",
+       "Coordinates:\n",
+       "  * x        (x) float64 2.0 6.0 10.0 14.0 18.0"
+      ]
+     },
+     "execution_count": 57,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "x_groups.apply(np.mean).rename({'x_bins': 'x'})"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Although there seems to be no way to bin directly in two dimensions, this can easily be achieved by using `apply` at two levels."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 58,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "<xarray.DataArray 'temperature' (x: 5, y: 5)>\n",
+       "array([[20.103486, 19.67291 , 19.81295 , 20.548091, 18.949756],\n",
+       "       [19.733658, 20.038455, 20.829428, 19.826022, 20.474313],\n",
+       "       [20.394431, 20.167488, 20.863185, 19.744571, 19.595792],\n",
+       "       [19.277913, 20.295705, 19.408287, 20.547187, 20.07851 ],\n",
+       "       [20.419735, 19.799297, 19.817082, 19.898053, 20.085402]])\n",
+       "Coordinates:\n",
+       "  * x        (x) float64 2.0 6.0 10.0 14.0 18.0\n",
+       "  * y        (y) float64 2.0 6.0 10.0 14.0 18.0"
+      ]
+     },
+     "execution_count": 58,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "coarse_temp = x_groups.apply(lambda x: x.groupby_bins('y', bins, labels=labels).apply(np.mean))\\\n",
+    "                      .rename({'x_bins': 'x', 'y_bins': 'y'})\n",
+    "coarse_temp"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "To verify, compare the upper-left and lower-right elements of `coarse_temp` with the explicitely computed mean value of those subarrays."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 59,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "True"
+      ]
+     },
+     "execution_count": 59,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "np.isclose(temperature[0:4, 0:4].mean(), coarse_temp[0, 0], rtol=1.0e-7)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 60,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "True"
+      ]
+     },
+     "execution_count": 60,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "np.isclose(temperature[-4:, -4:].mean(), coarse_temp[-1, -1], rtol=1.0e-7)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "We can visualize the coarsening process by plotting a heatmap of the original and the coarsened data."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 61,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<Figure size 720x360 with 3 Axes>"
+      ]
+     },
+     "metadata": {
+      "needs_background": "light"
+     },
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "vmin = float(temperature.min())\n",
+    "vmax = float(temperature.max())\n",
+    "figure, axes = plt.subplots(nrows=1, ncols=2, figsize=(10, 5))\n",
+    "# plot of tempeature\n",
+    "t_plot = axes[0].imshow(temperature, cmap='coolwarm', origin='lower',\n",
+    "                        vmin=vmin, vmax=vmax)\n",
+    "axes[0].set_xlabel('$x$')\n",
+    "tick_pos = list(range(0, 20, 5))\n",
+    "axes[0].set_xticks(tick_pos)\n",
+    "axes[0].set_xticklabels(f'{float(x):.1f}' for x in temperature.coords['x'][tick_pos])\n",
+    "axes[0].set_ylabel('$y$')\n",
+    "axes[0].set_yticks(tick_pos)\n",
+    "axes[0].set_yticklabels(f'{float(x):.1f}' for x in temperature.coords['y'][tick_pos])\n",
+    "figure.colorbar(t_plot)\n",
+    "# plot of coarse_temp\n",
+    "c_plot = axes[1].imshow(coarse_temp, cmap='coolwarm', origin='lower',\n",
+    "                        vmin=vmin, vmax=vmax)\n",
+    "axes[1].set_xlabel('$x$')\n",
+    "axes[1].set_xticks(range(len(coarse_temp.coords['x'])))\n",
+    "axes[1].set_xticklabels(f'{float(x):.1f}' for x in coarse_temp.coords['x'])\n",
+    "axes[1].set_ylabel('$y$')\n",
+    "axes[1].set_yticks(range(len(coarse_temp.coords['y'])))\n",
+    "axes[1].set_yticklabels(f'{float(x):.1f}' for x in coarse_temp.coords['y'])\n",
+    "plt.tight_layout()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Time series"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Working with multi-dimensional time series data is straightforward with xarray.  A sequence of timestamps can be created using pandas. We will use this to index a 3D array, where the third dimension represents time."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 62,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "x_coords = np.linspace(-2.0, 2.0, 5)\n",
+    "y_coords = np.linspace(-3.0, 3.0, 7)\n",
+    "timestamps = pd.date_range('2019-07-01', freq='6H', periods=10)\n",
+    "data = xr.DataArray(np.empty((len(x_coords), len(y_coords), len(timestamps))),\n",
+    "                    dims=('x', 'y', 't'), coords=(x_coords, y_coords, timestamps))"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "We initialize the data, starting from random values at $t = 0$, and computing the data at $t + 1$ from the data at time $t$."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 63,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "data[:, :, 0] = np.random.normal(loc=0.0, scale=1.0, size=(data.coords['x'].shape[0], data.coords['y'].shape[0]))\n",
+    "for t in range(1, data.coords['t'].shape[0]):\n",
+    "    data[:, :, t] = data[:, :, t - 1] + np.random.normal(loc=0.0, scale=0.1, size=data[:, :, 0].shape)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "For each timestamp, we can print the mean and standard deviation over the data."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 64,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "mean: -0.011, stddev: 0.095\n",
+      "mean: +0.025, stddev: 0.077\n",
+      "mean: -0.038, stddev: 0.079\n",
+      "mean: -0.028, stddev: 0.104\n",
+      "mean: +0.013, stddev: 0.102\n",
+      "mean: +0.035, stddev: 0.098\n",
+      "mean: +0.011, stddev: 0.072\n",
+      "mean: +0.011, stddev: 0.101\n",
+      "mean: -0.007, stddev: 0.105\n"
+     ]
+    }
+   ],
+   "source": [
+    "for t in range(1, data.coords['t'].shape[0]):\n",
+    "    diff = data.isel(t=t) - data.isel(t=t - 1)\n",
+    "    print(f'mean: {float(diff.mean()):+0.3f}, stddev: {float(diff.std()):0.3f}')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 65,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "mean_data = data.mean(dim=('x', 'y'))\n",
+    "mean_data.name = 'mean values'"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 66,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYgAAAEfCAYAAABbIFHdAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjAsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+17YcXAAAgAElEQVR4nO3dd3yV9fn/8deVnbBHBiMhYUMQRMJWFBdYRVvFgVoZWldpv+2346fdte23dtja1j3AvVcRFdxamQkrEGbYIQkEwg4h6/r9cQ41hiMcwrnPfcb1fDzOg5xz7nPuN8mdXOf+3J8hqooxxhjTVIzbAYwxxoQmKxDGGGN8sgJhjDHGJysQxhhjfLICYYwxxicrEMYYY3xytECIyHgRWScixSJyl4/nx4jIUhGpE5GJTZ6rF5Hl3tssJ3MaY4w5njg1DkJEYoH1wEVACZAPTFLV1Y22yQZaAz8GZqnqa42eO6SqLR0JZ4wx5qTiHHzvYUCxqm4CEJGXgCuA/xYIVd3ifa7BwRzGGGOawckC0QXY3uh+CTD8FF6fJCIFQB1wr6q+daKNO3bsqNnZ2acc0hhjotmSJUt2q2qqr+ecLBDi47FTac/KUtVSEekOfCwiK1V141d2IHIrcCtAVlYWBQUFzU9rjDFRSES2ft1zTl6kLgEyG93vCpT6+2JVLfX+uwn4FBjsY5vHVDVPVfNSU30WQGOMMc3kZIHIB3qJSI6IJADXAX71RhKRdiKS6P26IzCaRtcujDHGOM+xAqGqdcB0YC6wBnhFVYtE5B4RuRxARIaKSAlwNfCoiBR5X94PKBCRFcAneK5BWIEwxpggcqyba7Dl5eWpXYMwxphTIyJLVDXP13M2ktoYY4xPViCMMcb4ZAXCGGOMT1YgjDGmGYpK9/PUvM0cqal3O4pjnBwoZ4wxEemLDbu59dkCqmrqefw/m7n7G3259IxOiPgaHxy+7AzCGGNOwbsry5j61GKy2qfwyI1DaJMcz/QXlnHtowtZtWO/2/ECygqEMcb46flFW/nuC0sZ1LUtL986kvEDMnj7e2fzxyvPoLjiEBMe+IK73yhk96GjbkcNCCsQxhhzEqrKAx9v4OdvrmJsnzSevXk4bVLiAYiNESYNy+KTH5/HtNE5vFpQwti/fMoT/9lETV14T1RtBcIYY06goUG5Z/Zq/vr+er41uAuPfnsIyQmxx23XJjmeX17Wnzk/GMNZ3drx+3fWMP4fn/PJul0upA4MKxDGGPM1ausb+NGrK5g5bwvTRudw39WDiI898Z/NnmkteXraMGZOGQoKU2fmM3XmYjZWHApS6sCxqTaMMcaHIzX1fPeFpXy8dhc/GdeHO8/rccq9lGrqGnhmwRb+8eEGjtTWM2VUNt+/sBetk+KdCd0MJ5pqwwqEMcY0sb+qlpufzmfJtr38/psDuGF4t9N6v92HjnLf++t4KX877VMS+PG4PlyTl0lsjPvdYm0uJmOM8dPOA9Vc+9gCCkv28+D1Z512cQDo2DKRP145kLenn0331Bbc/cZKLn/gCxZvrgxAYudYgTDGGK8tuw8z8ZH5bKusYsaUoXzjjE4Bff8BXdrwym0j+dekwew9XMM1jy5g+gtL2bHvSED3Eyg2ktoYY/BMnTF5Rj71DQ28+J0RDMps68h+RIQJgzpzYb90Hv18I498tpEP1+zktjE9uP3cHj57SLnFziCMMVFv0aY9XPfoQhJihVdvH+VYcWgsOSGWH1zYm49+dB4X9kvnHx9t4IL7PmXWilJC5dqwFQhjTFT7YPVObpqxmLTWibx2xyh6prUM6v67tE3mgevP4pXbRtKuRQLff3EZ1zy6ICSm7bACYb5i0aY93Pn8Emrrw3sEqDH+eLVgO7c/t4S+nVrz6u2j6Nw22bUsw3LaM2v62dx75RlsqjjMhAe+4K7X3Z22wwqE+S9V5XfvrObdleUs3LTH7TjGOOqxzzfyk9cKGdWjAy/cMpz2LRLcjkRsjHDdsCw++cl53HJ2Dq8t8Uzb8fjn7kzb4WiBEJHxIrJORIpF5C4fz48RkaUiUiciE30831pEdojIA07mNB6fra9g1Y4DAMwtKnc5jTHOUFXufW8t//fuWi49oxNPTM6jRWJo9ddpnRTPzy/tz9wfjmFoTnv+8O4axt//OZ+sDe60HY4VCBGJBR4ELgH6A5NEpH+TzbYBU4AXvuZtfgd85lRG8yXPZGTFdG6TxIX90ni/aCcNDaFxocyYQKmrb+Cu11fyyGcbuWF4Fv+cNJjEuNDpNdRUj9SWzJgylJlTh4LA1KfymTJzMcW7gjNth5NnEMOAYlXdpKo1wEvAFY03UNUtqloIHHfuJCJDgHTgfQczGq9Fmysp2LqX28/rwWUDO7Pr4FGWbd/ndixjAqa61jN1xssF2/n++T35/TcHhMRIZn+M7ZPGnP8Zwy8u7ceSLXsZf//n/G72avYfqXV0v04WiC7A9kb3S7yPnZSIxAD3AT9xIJfx4YGPi+nYMpFr8jIZ2zeN+FjhfWtmMhHiYHUtU2fmM7doJ7+e0J//vbhP2K3+lhAXwy3ndOeTn5zH1XmZzJi3mbF//ZQXFm2j3qGzfScLhK/vvr//izuBd1V1+4k2EpFbRaRARAoqKipOOaDxWL59H18U7+bWMTkkxcfSJjmekT06MqeoPGT6YxvTXLsPHWXS4wvJ31LJ/deeydTROW5HOi2eaTvO4O3pZ9MztSU/e3Ml1z22wJHfVSevzJQAmY3udwVK/XztSOAcEbkTaAkkiMghVf3KhW5VfQx4DDyT9Z1+5Oj0wMfFtE2J/8qcM+Ny0/n5m6tYt/MgfTNau5jOmOYr2VvFt59cTNn+Izx+Ux5j+6a5HSlgBnRpw8u3jeCdlWXsP1LryBmRk2cQ+UAvEckRkQTgOmCWPy9U1RtUNUtVs4EfA880LQ4mMNaUHeDDNTuZNjrnKz05LuqfjgjMWWXNTCY8rd95kKsens+eQ0d57ubhEVUcjhERLhvYOSATCvriWIFQ1TpgOjAXWAO8oqpFInKPiFwOICJDRaQEuBp4VESKnMpjfHvwk2JaJsYxeWT2Vx5Pa5XEkKx2zC3a6U4wY07Dkq17ufqRBajCK7ePJC+7vduRwpKjnX9V9V3g3SaP/arR1/l4mp5O9B5PAU85EC/qbaw4xDsry7j93B7/XV+3sfEDMvj9O2vYtqeKrA4pLiQ05tR9um4Xdzy3lPTWiTx783Ay29ux21w2kjqKPfzpRhLjYrj5bN8X7cblZgA2aM6Ej38v38EtTxeQ07EFr94+yorDabICEaW2V1bx5rIdTBqWRceWiT63yWyfQr9Ora1AmLDwzIIt/ODl5Qzp1o6XbhtBaivfx7XxnxWIKPXo5xuJFeHWMd1PuN343AyWbNvLroPVQUpmzKlRVf7+wXp+9e8iLuyXztPThoXUms/hzApEFNp5oJpX8ku4akhXOrU58eyV4wako+qZEtmYUNPQoPx6VhH/+GgDVw/pysM3nEVSfOhOnRFurEBEocc/30S9Knec2+Ok2/ZJb0V2hxTrzWRCTk1dA//z8nKeWbCV28Z0588TBxIXa3/SAsm+m1Gm8nANzy/axhWDOvvVM0lEGJebwfzi3Y7P+2KMv6pq6rjlmQLeXlHK3Zf05e5v9Au7qTPCgRWIKDPji81U19Vz59iTnz0cM25ABnUNGvSpho3xZe/hGm54YhFfbKjgz1cN5DY/zoRN81iBiCL7j9Ty9PwtXDIgg55prfx+3Zld25LWKtFGVRvXba+s4qpH5lNUeoCHbxzCNUMzT/4i02yhtUqGcdSzC7Zw8Ggdd57X85ReFxMjXJybzutLdnCkpp7kBLsIaIKvsGQf057Kp7Zeef6W4Qy10dGOszOIKFFVU8eTX2zm/L5pDOjS5pRfPz63E0dq6/l8g82aa4Lvk7W7uPbRhSTGxfL6HaOsOASJFYgo8cKibeytquW7Y0/t7OGY4d3b0yY53gbNmaB7cfE2bnmmgB5pLXjzu6PomdbS7UhRw5qYokB1bT2Pfb6JUT06MKRbu2a9R3xsDBf0S+OjNbuorW8g3roTGocdGwD3z4+LObd3Kg/dcFbIrR0d6ey3PAq8uqSEXQePMr2ZZw/HjMvNYP+RWhZtqgxQMmN8q6lr4MevFvLPj4u5Ni+TJybnWXFwgRWICFdb38Ajn27krKy2jOzR4bTea0yvVJLiY6yZyTjqYHUtNz+dz+tLS/jhhb2596oz7IzVJfZdj3BvLdvBjn1HmH5+z9MeSJScEMt5vdOYW1ROg0Nr4JrotvNANdc8upAFG/fw54kD+Z8Le9kAOBdZgYhg9Q3Kw59upH+n1oztE5jVtMYNSGfXwaMsL9kXkPcz5pj1Ow/yrQfnsW3PYZ6cMpRr8myMg9usQESw91aVsWn34YCcPRxzft904mLEmplMQC3YuIerHp5PbYPy8m0jObd3qtuRDFYgIpaq8sDHxfRIbcF478I/gdAmOZ6RPTowd1U5qtbMZE7frBWlTJ6xmPTWSbx556hmjdMxzrACEaE+WrOLteUH+e7YnsTEBLYNd1xuBlv2VLF+56GAvq+JLqrKo59t5PsvLuPMrLa8fvsourazFeBCiaMFQkTGi8g6ESkWkbt8PD9GRJaKSJ2ITGz0eDcRWSIiy0WkSERudzJnpFFV/vVJMZntk7l8UOeAv//F/dMRweZmMs1W36D8ZlYRf3xvLZcO7MQz04b5XBfduMuxAiEiscCDwCVAf2CSiPRvstk2YArwQpPHy4BRqnomMBy4S0QC/5cuQs0r3sOK7fu449yejsyPn9Y6ibOy2tl1CNMs1bX13PHcEp5esJXvnJPDv64bbIv8hCgnzyCGAcWquklVa4CXgCsab6CqW1S1EGho8niNqh713k10OGfE+dfHG8honcRVQ7o4to/xuRmsLjvA9soqx/ZhIk/l4RomPb6QD9bs5NcT+vPzS/sHvAnUBI6Tf3i7ANsb3S/xPuYXEckUkULve/xJVUsDnC8i5W+pZNHmSm4d053EOOc+lY3zXvi2swjjr617DnPVw/NZXXqAh284i6mjc9yOZE7CyQLh62OB391eVHW7qg4EegKTRST9uB2I3CoiBSJSUFFhs4wCPPBxMR1aJDBpWJaj+8nqkEK/Tq2tQBi/rNi+jysfms/eqhpe+M5wxg/o5HYk4wcnC0QJ0HikS1fglM8CvGcORcA5Pp57TFXzVDUvNdX6Ta8s2c9n6yu4+ZycoKzZMC43nYKte6k4ePTkG5uo9dGanVz32EJSEj1TdQ/pZlN1hwsnC0Q+0EtEckQkAbgOmOXPC0Wkq4gke79uB4wG1jmWNEI8+EkxrZPi+PaIbkHZ37jcDFThg9U7g7I/E36eX7SV7zxTQM+0lrxxx2h6pNpU3eHEsQKhqnXAdGAusAZ4RVWLROQeEbkcQESGikgJcDXwqIgUeV/eD1gkIiuAz4C/qupKp7JGgvU7DzKnqJwpo3NolRSc7oJ9M1rRrUOKNTOZ46gqf5m7lp+/uYpze6fy0q0jSG2V6HYsc4ocnT9XVd8F3m3y2K8afZ2Pp+mp6es+AAY6mS3SPPRJMSkJsUwdlR20fYoI43IzmDlvMweqa2kdpMJkQltNXQP/7/VC3ly2g0nDMvndFQMc6W5tnGc/NeDjtTs5Wlfvdoxm27L7MLNWlHLjiG60a5EQ1H2Py82gtl75ZO2uoO7XhKYD1bVMfWoxby7bwY8v7s3/fesMKw5hLOp/csW7DnHz0wVMeyqfg9W1bsdplkc+20hcbAy3nBP8boODM9uS1irRRlUbyvYf4ZpHFrBoUyX3XT2I6efbVN3hLuoLRM+0lvx14iAWbqrkuscWhl2PnNJ9R3h9aQnXDc0krVVS0PcfEyNc1D+dT9dVUF0bvmdh5vSsLT/AlQ/Np2TvEWZOHcpVQ45rOTZhKOoLBMBVQ7ryxOQ8NlUcZuIj89m657Dbkfz22OebUIXbzu3hWobxAzI4UlvP5+ttLEo0ml+8m6sfXkCDKq/cNpJzelmX80hhBcJrbJ80XvjOcA4cqeWqh+ezasd+tyOdVMXBo7y4eBtXntWFLm2TXcsxonsHWifFMbfIurtGm7eW7WDyzMVktEnijTtH079za7cjmQCyAtHI4Kx2vHbHKBLjYrn20QV8sWG325FO6IkvNlFb38Ad5/V0NUd8bAwX9kvno7U7qa1vOPkLTNhTVR76tJgfvLycs7La8drto1z9kGKcYQWiiR6pLXnjzlFktk9h6lOLmbUiNKeA2ldVw3MLtnLZwM7kdGzhdhwuzs1gX1UtizdXuh3FOKy+Qfnlv1fx5znrmDCoM8/cbFN1RyorED6kt07i5dtGMjirHd9/cRkz5212O9JxZs7bwuGaer471t2zh2PO7Z1KUnyMDZqLcEdq6rnt2SU8t3Abt53bnX9ce6ajk0Iad1mB+BptkuN5ZtowxuWm89u3V/OnOWtDZonNg9W1PDV/Cxf3T6dPRiu34wCQnBDLub1TmVtUTkNDaHyfTGBV19Yz6fGFfLR2J/dckcvdl/SzqbojnBWIE0iKj+WhG4Zw/fAsHv50Iz95rTAk2tifW7iN/UdqmX5+aJw9HDMuN4OdB46yomSf21GMA+YWlbN8+z7+ds0gbhqZ7XYcEwRWIE4iNkb4wzcH8IMLe/HakhJue3YJR2rc6+9/pKaeJ7/YxJjeqQzs2ta1HL5c0DeduBix3kwR6u0VZWS0TuKKQc4tRGVCixUIP4gIP7iwN7//5gA+XbeL659YyN7DNa5keSl/G7sP1TA9RK49NNYmJZ6RPTowt6g8ZJrjTGDsP1LL5+sruHRgJ2tWiiJWIE7BjSO68dANQygqPcDER+azY9+RoO7/aF09j32+iWE57RmWE5pz6o/LzWDz7sNs2HXI7SgmgD5YvZOa+gYuG2gL/UQTKxCnaPyADJ6dNoxdB49y1UPzWVd+MGj7fmPpDsr2V4fk2cMxF/dPRwSbmynCzC4spWu7ZM7MDK1mTeMsKxDNMLx7B169fSQNqlz9yHzytzjf97+uvoGHP93IoK5tOKdXR8f311xprZMYnNnWurtGkL2Ha/hiw24uHdjJJt+LMlYgmqlvRmtev2MUHVsmcuMTi3jf4T+IbxeWsq2yiu+O7Rnyv6TjB2RQVHqA7ZVVbkcxATCnqJy6BmXCwM5uRzFBdtICISI9RCTR+/V5IvJ9EbHzTCCzfQqv3TGKvp1ac/tzS3hx8TZH9tPQoDz0yUb6ZrTiwn7pjuwjkMblZgDYWUSEmF1YSk7HFuTaPEtRx58ziNeBehHpCTwJ5AAvOJoqjLRvkcCL3xnOmN6p3P3GSv750YaA9+B5f3U5G3Yd4s6xPcOiB0m3Di3om9GK9627a9irOHiUBRv3cJk1L0UlfwpEg3d96W8B96vqDwHrytBISkIcj9+Ux5VndeFvH6znV/8uoj5Ao4lVlX99XExOxxZcekb4fNvH5WaQv7Uy7NbXMF/13qoyGhQus+alqORPgagVkUnAZGC29zG/ZuYSkfEisk5EikXkLh/PjxGRpSJSJyITGz1+pogsEJEiESkUkWv92Z+b4mNjuO/qQdx2bneeXbiV7724NCAL6Hy6voKi0gPccV4PYsPg7OGYcbkZqMKHa+wsIpzNXlFGr7SWITOliwkufwrEVGAk8AdV3SwiOcBzJ3uRiMQCDwKXAP2BSSLSv8lm24ApHN9kVQXcpKq5wHjg/nC47iEi3H1JP35xaT/eXVnO5BmLOXAay5iqKg98XEyXtsl8a3B4jV7t16kVWe1TrLtrGCvfX03+1komDLKzh2h10gKhqquB/wcs9d7frKr3+vHew4BiVd2kqjXAS8AVTd57i6oWAg1NHl+vqhu8X5cCu4CwWabqlnO6c/+1Z7Jk616ufXQhuw5UN+t9Fm6qZMnWvdx+bnfiw2zhdxFhXG468zfuPq0iadzzzsoyVLHBcVHMn15ME4DlwBzv/TNFZJYf790F2N7ofon3sVMiIsOABGDjqb7WTd8c3IUZU4aydc9hrnx4PpsqTn1k8QOfbCC1VSJX52U6kNB54wdkUFuvfLJ2l9tRTDO8vaKU/p1a0z21pdtRjEv8+Vj6GzxnA/sAVHU5np5MJ+OrwfyUrtyKSCfgWWCqqh43jaqI3CoiBSJSUFEReushj+mdyku3juBITT0TH1nAiu3+z3K6dNte5hXv4dZzupMUH57z7Q/ObEdqq0Tr7hqGtldWsXz7Pi4bZGcP0cyfAlGnqk0XaPbnD30J0Pijb1fA7+XZRKQ18A7wC1Vd6GsbVX1MVfNUNS81NTRboAZ2bctrd4yiRWIskx5fyGfr/StkD35cTNuUeK4fnuVwQufExAgX9U/n03UVAblgb4LnnZVlADY4Lsr5UyBWicj1QKyI9BKRfwHz/XhdPtBLRHJEJAG4DvCnaQrv9m8Cz6jqq/68JpTldGzB63eMoluHFtz8VD5vLis54fZFpfv5aO0ubh6dQ4vEuCCldMb43Ayqaur5T4iv722+anZhKYMy25LZPsXtKMZF/hSI7wG5wFHgReAA8IOTvcg7dmI6MBdYA7yiqkUico+IXA4gIkNFpAS4GnhURIq8L78GGANMEZHl3tuZp/h/CylprZJ4+bYR5GW344cvr+Dxzzd97bYPfbKRVolx3DQqO3gBHTKiewdaJcVZM1MY2bz7MKt2HGCCXZyOeif9eKqqVcDPvbdToqrvAu82eexXjb7Ox9P01PR1z+FHV9pw0zopnqenDeN/X17BH95dQ8Who9w1vu9XRkcX7zrEu6vKuPO8HrRJDv+F4BPiYriwXzofrtlJXX0DcWHWGysazV7haQn+RhgNzDTOOGmBEJFP8HHNQVXPdyRRhEuMi+WfkwbToWUCj32+iYqDR/nzxIH/7cb68KcbSYqLZdpof/oBhIdxuem8uWwHizdXMqpn6M5EazxmF5YxNLsdndsmux3FuMyfBu4fN/o6CbgKqHMmTnSIjRF+e3kuaa0S+ev769lzuIaHbziLysM1vLV8B5NHZtOhZaLbMQNmTO9UkuJjmFtUbgUixG3YeZB1Ow/y28tz3Y5iQoA/TUxLmjw0T0Q+cyhP1BARpp/fi44tE/nZmyu5/vGFdOvQglgRbh3T3e14AZWSEMeYXqnMLdrJryfkhsWEg9Hq7cIyYgQuOSPD7SgmBPgzUK59o1tHERkH2NETINcNy+LRb+extvwgs1aUMjGvKxltktyOFXDjcjMoP1BN4Y6mPaZNqFBVZq8oZXhOB9JaRd4xaE6dP01MS/BcgxA8TUubgZudDBVtLuqfzvO3DOehTzeG9HKip+OCfmnExQhzi8pt2coQtbrsAJt2H+aWcyLrDNY0nz9NTJFztTSE5WW3Z8aU9m7HcEzblARGdO/A3FXl/HRcH1tbIATNLiwjNkYYP8AaCIzH1xYIEbnyRC9U1TcCH8dEsnEDMvjlW6so3nWIXuk2fXQoUVVmF5YyumdH2rdIcDuOCREnOoOYcILnFLACYU7Jxf3T+eVbq5izqtwKRIhZUbKf7ZVH+N75vdyOYkLI1xYIVZ0azCAm8qW3TmJwVlvmri7nexfYH6JQMntFKfGxwrj+1rxkvuTXRD8icime6Tb+27VBVe9xKpSJXONzM/jje2vZXlll8/yEiIYG5Z2VZZzbO5U2KeE/et8Ejj/dXB8BrsUzJ5PgmTepm8O5TIQal+v5hPr+aluKNFQs3baXsv3Vtu60OY4/E+OMUtWbgL2q+ls8y4+G5wo2xnXZHVvQN6OVTd4XQt5eUUpiXAwX9k93O4oJMf4UiCPef6tEpDNQi38LBhnj08W5GeRvqWT3oaNuR4l69Q3Ku6vKGdsnjZZhPrW8CTx/CsRsEWkL/AXPutRb8Ez7bUyzjMtNRxU+tGYm1y3avIeKg0eZMMial8zxTlogVPV3qrpPVV/Hc+2hb+Mpu405Vf07tSazfTJzrJnJdbMLy0hJiOX8vmluRzEhyJ+L1CtE5Gci0kNVj/pYftSYUyLi6U45v3gPB6tr3Y4TtWrrG3hvZRkX9EsnOSE81z03zvKnielyPHMwvSIi+SLyYxEJ34WSTUgYPyCDmvoGPlnn3xrdJvDmb9zD3qpaLrOV48zX8KeJaauq/llVhwDXAwPxTNhnTLOdldWOji0TmbvKmpncMntFKa0S4zi3d6rbUUyI8negXDaedaKvBeqBnzoXyUSDmBjh4tx03lq2g+raepLirYkjmI7W1TO3qJyLctPte2++lj/XIBbhmXcpBrhaVYep6n3+vLmIjBeRdSJSLCJ3+Xh+jIgsFZE6EZnY5Lk5IrJPRGb7+X8xYWZcbgZVNfV8sWG321Gizn/W7+ZAdR0TbHCcOQF/rkFMVtWzVPVeVd3k7xuLSCzwIHAJ0B+YJCL9m2y2DZgCvODjLf4CfNvf/ZnwM7J7B1olxdmgORfMLiylTXI8o20JWHMC/lyDWNvM9x4GFKvqJlWtAV4Crmjy3ltUtRBo8LHfj4CDzdy3CQMJcTFc0DeND9fspK7+uEPAOKS6tp4PVu/kkgEZJMT58xnRRCsnj44uwPZG90u8jxnzX+NyM9hbVcviLZVuR4kan67bxeGaept7yZyUkwXC15JhGtAdiNwqIgUiUlBRYd0lw9G5fVJJjIvh/SIbVR0sb68oo0OLBEZ0j9wVDE1g+FUgRGSUiFwvIjcdu/nxshK+OqlfV6C0OSG/jqo+pqp5qpqXmmpd9cJRSkIcY3qnMreoHNWAfn4wPhw+WsdHa3dyyRkZxMVa85I5MX96MT0L/BU4GxjqveX58d75QC8RyRGRBOA6YNZpZDURalxuBmX7qykssUH6Tvto7S6qaxus95Lxiz/jIPKA/nqKH+9UtU5EpgNzgVhghqoWicg9QIGqzhKRocCbQDtggoj8VlVzAUTkP0BfoKWIlAA3q+rcU8lgwsOF/dKIjRHmFpUzKLOt23Ei2uwVpaS3TmRotjUvmZPzp0CsAjKAslN9c1V9F3i3yWO/avR1Pp6mJ1+vPedU92fCU9sUT3v4nKJyfjq+r9txItaB6lo+XV/BDcOziInxdYnQmK/ypxGyI7BaROaKyKxjN6eDmegyPjeDTY0tuHsAAB0TSURBVBWHKd5lPZud8kHRTmrqGqz3kvGbP2cQv3E6hDEX9c/gl/8uYs6qcqaf38rtOBFpdmEpXdomc1aWNeMZ/5y0QKjqZ8EIYqJbRpskzsxsy9yinUw/v5fbcSLOvqoa/rNhNzefnYOINS8Z//jTi2mEd5rvQyJSIyL1InIgGOFMdBk/IIOVO/ZTsrfK7SgRZ25ROXUNas1L5pT4cw3iAWASsAFIBm7xPmZMQI3LzQCwQXMOeHtFGd06pDCgS2u3o5gw4tdIGVUtBmJVtV5VZwLnOZrKRKWcji3ok97KJu8LsN2HjjJ/424uG9jJmpfMKfGnQFR5B7otF5E/i8gPgRYO5zJRalxuOvlbKtlz6KjbUSLGe6vKaVCYMMial8yp8adAfNu73XTgMJ7pM65yMpSJXuMGZNCg8OEaa2YKlNkrSumZ1pI+6dY7zJwav5YcxTPxXidV/a2q/q+3ycmYgOvfqTVd2yUzx5YiDYidB6pZvKXSmpdMs/jTi2kCsByY471/pg2UM04REcblZjCveA8Hq2vdjhP23iksQxXrvWSaxZ8mpt/gWfxnH4CqLgeynYtkot34ARnU1Dfw6Tqbwv10zS4spV+n1vRMa+l2FBOG/CkQdapq02yaoDkrqx0dWyYwx3oznZaSvVUs3baPywZ2cjuKCVP+FIhVInI9ECsivUTkX8B8h3OZKBYbI4wfkMGHq3ey93CN23HC1juFnvk1bWpv01z+FIjvAbnAUeBF4ADwAydDGfPtEdkcrWvgxfxtbkcJW7MLyxjYtQ1ZHVLcjmLClD+9mKpU9eeqOtS7etvPVbU6GOFM9OqT0Yqze3bkmflbqa1vcDtO2Nmy+zArd+y3swdzWvzpxZQnIm+IyFIRKTx2C0Y4E92mjs6m/EC1dXlthndWepqXLrXrD+Y0+DPd9/PAT4CVgH2UM0Eztk8a2R1SmDFvs40CPkVvryhlSLd2dG6b7HYUE8b8uQZRoaqzVHWzqm49dnM8mYl6MTHClFHZLNu2j2Xb9rodJ2wU7zrI2vKD1nvJnDZ/CsSvReQJEZkkIlceuzmezBhgYl4mrRLjmDlvi9tRwsbbK8oQgUvPsAJhTo8/BWIqcCYwHpjgvV3mz5uLyHgRWScixSJyl4/nx3ivbdSJyMQmz00WkQ3e22R/9mciT8vEOK4dmsm7K8so3299I05GVZldWMrwnPaktU5yO44Jc/4UiEHe3kuTVXWq9zbtZC8SkVjgQeASoD8wSUT6N9lsGzAFeKHJa9sDvwaG4xnF/WsRaedHVhOBJo/KpkGVZxducTtKyFtTdpCNFYdtag0TEP4UiIU+/rD7YxhQrKqbVLUGeAm4ovEGqrpFVQs5/uL3OOADVa1U1b3AB3jOYEwUymyfwkX903lh0Taqa+vdjhPSZheWEhsjXDIgw+0oJgL4UyDOxrMWxDpvF9eVfnZz7QJsb3S/xPuYP07ntSYCTR2dw96qWt5atsPtKCHL07xUxqgeHejQMtHtOCYC+NPNtbmf3H3NLayBfK2I3ArcCpCVleV/MhN2hue0p3+n1syYt5lrh2ba1NU+rNyxn22VVUwf29PtKCZC+LUehK+bH+9dgmdxoWO6AqV+5vLrtar6mPf6SF5qaqqfb23CkYgwdXQ263ceYl7xHrfjhKTZhWXEx8p/1/Y25nT5tSZ1M+UDvUQkx7tk6XWAv+tIzAUuFpF23ovTF3sfM1FswqDOdGyZwMx5m92OEnIaGpTZK0o5p1cqbVLi3Y5jIoRjBUJV6/AsUzoXWAO8oqpFInKPiFwOICJDRaQEuBp4VESKvK+tBH6Hp8jkA/d4HzNRLCk+lhuGd+OjtbvYvPuw23FCyrLteyndX22D40xAOXkGgaq+q6q9VbWHqv7B+9ivVHWW9+t8Ve2qqi1UtYOq5jZ67QxV7em9zXQypwkfN4zIIj5WeHr+FrejhJS3V5SREBfDRf3T3Y5iIoijBcKYQEtrlcSEQZ15tWA7B2xJUgDqG5R3V5Yxtk8qrZKseckEjhUIE3amjc7hcE09r+RvP/nGUWDx5kp2HTxqg+NMwFmBMGFnQJc2DMtuz1Pzt1Df4G/P6cg1u7CU5PhYLuiX5nYUE2GsQJiwNHV0NiV7j/DB6p1uR3FVXX0Dc1aVc0G/NFIS/BnWZIz/rECYsHRR/3S6tE2O+i6vCzbtYc/hGmteMo6wAmHCUlxsDFNGZbNocyVFpfvdjuOat1eU0jIxjvP62EBRE3hWIEzYumZoJikJsVG7VkRNnad56aL+6STFx7odx0QgKxAmbLVJjmfikK7MWl5KxcGjbscJui+KKzhQXceEQTY4zjjDCoQJa5NHZVNT38ALi7a5HSXoZq8oo01yPGf3tOYl4wwrECas9Uhtydg+qTy7cCtH66JnrYjq2nreX72TcbnpJMTZr7Fxhh1ZJuxNHZ3D7kNHmb2izO0oQfPpugoOHa2z3kvGUVYgTNg7p1dHeqa1ZMa8zahGx8C52YWltG+RwKgeHdyOYiKYFQgT9kSEaaNzKCo9QP6WvW7HcVxVTR0frdnFJQMyiIu1X2HjHDu6TET41uAutE2Jj4qBcx+t2cWR2nprXjKOswJhIkJyQiyThmUxt6ic7ZVVbsdx1OzCUlJbJTIsp73bUUyEswJhIsa3R3RDRHh2oT8r4oang9W1fLKugkvP6ERsjK3LbZxlBcJEjM5tk7lkQAYvLt7G4aN1bsdxxIdrdlJT12CD40xQWIEwEWXq6BwOVtfx+tISt6M44u0VZXRuk8TgzHZuRzFRwAqEiShnZbVlUGZbnpq3hYYIWytif1Ut/9lQwaUDOxFjzUsmCBwtECIyXkTWiUixiNzl4/lEEXnZ+/wiEcn2Pp4gIjNFZKWIrBCR85zMaSKHp8trNpt2H+az9RVuxwmouUXl1Nar9V4yQeNYgRCRWOBB4BKgPzBJRPo32exmYK+q9gT+DvzJ+/h3AFT1DOAi4D4RsbMd45dvnNGJ9NaJzIiwLq9vF5aS1T6FgV3buB3FRAkn/+gOA4pVdZOq1gAvAVc02eYK4Gnv168BF4iI4CkoHwGo6i5gH5DnYFYTQeJjY7hpZDb/2bCbDTsPuh0nIPYcOsr8jXu4bGAnPL8ixjjPyQLRBWi8qnyJ9zGf26hqHbAf6ACsAK4QkTgRyQGGAJkOZjURZtKwLBLjYpg5f4vbUQLivVXl1DdY85IJLicLhK+POU2vGn7dNjPwFJQC4H5gPnBcv0URuVVECkSkoKIistqbzelp3yKBbw3uwhtLS9h7uMbtOKdtdmEp3VNb0K9TK7ejmCjiZIEo4auf+rsCpV+3jYjEAW2ASlWtU9UfquqZqnoF0BbY0HQHqvqYquapal5qqs2Jb75qyuhsqmsbeDE/vNeKeGnxNhZuquTKwV2seckElZMFIh/oJSI5IpIAXAfMarLNLGCy9+uJwMeqqiKSIiItAETkIqBOVVc7mNVEoL4ZrRndswPPLthKbX2D23Ga5cPVO/nZmysZ0zuV287t4XYcE2UcKxDeawrTgbnAGuAVVS0SkXtE5HLvZk8CHUSkGPhf4FhX2DRgqYisAf4f8G2ncprINm10DmX7q5mzqtztKKdsydZKvvvCUgZ0acPDN5xFvM3caoJMImX+/Ly8PC0oKHA7hgkxDQ3K+fd9SvsWCbxx52i34/iteNdBrnp4Ae1S4nntjlF0bJnodiQToURkiar67CVqH0lMRIuJEaaMymbptn0s377P7Th+Kdt/hJueXEx8bAzPTBtuxcG4xgqEiXgT8zJplRgXFmtF7K+qZfKMxRyoruOpqUPJ6pDidiQTxaxAmIjXMjGOa4Zm8k5hGeX7q92O87Wqa+u55Zl8Nu8+zGPfHsKALjZi2rjLCoSJCpNHZlOvynMhulZEfYPy/ReXUbB1L3+75kxG9ezodiRjrECY6JDVIYWL+qXz/KKtVNfWux3nK1SVX/57Fe+v3smvLuvPhEE2WtqEBisQJmpMHZ3D3qpa3lq2w+0oX/GPjzbwwqJt3HFeD6aOznE7jjH/ZQXCRI0R3dvTr1NrZs7bQqh0735h0Tbu/3ADV53VlZ+O6+N2HGO+wgqEiRrH1opYt/Mg8zfucTsOc4vK+cVbKxnbJ5V7rzrDptEwIccKhIkqEwZ1pkOLBNe7vOZvqeT7Ly7jjK5tedBGSZsQZUeliSpJ8bHcMKIbH63dxZbdh13JsH7nQW5+Kp8ubZOZOWUoKQlxruQw5mSsQJioc+OILOJihKdcWCuidN8RJs9YTFJ8LE9PG0b7FglBz2CMv6xAmKiT1iqJCQM782rBdg5U1wZtv/uqarhpxmIOVdfx9LRhZLa3UdImtFmBMFFp6ugcDtfU80r+9pNvHADVtfXc/HQB2/ZU8dhNefTr1Doo+zXmdFiBMFHpjK5tGJrdjqcXbKG+wdkur3X1DUx/YRlLt+3l/uvOZGSPDo7uz5hAsQJhota00TlsrzzCh2t2OrYPVeUXb63iwzU7+e3luXzjjE6O7cuYQLMCYaLWRf3TPT2JHOzy+vcP1vNS/namj+3JTSOzHduPMU6wAmGiVlxsDJNHdWPhpkqKSvcH/P2fXbiVf35czDV5XfnRxb0D/v7GOM0KhIlq1+ZlkRwfy1PztgT0feesKuNX/17FBX3T+L9v2ShpE56sQJio1iYlnolDuvLv5aXsPnQ0IO+5cNMevv/ScgZntuWB688izkZJmzDl6JErIuNFZJ2IFIvIXT6eTxSRl73PLxKRbO/j8SLytIisFJE1InK3kzlNdJsyOpua+gaeX7jttN9rbfkBvvNMAZntknly8lCSE2IDkNAYdzhWIEQkFngQuAToD0wSkf5NNrsZ2KuqPYG/A3/yPn41kKiqZwBDgNuOFQ9jAq1HakvO65PKc4u2crSu+WtFlOytYvKMxaQkxPLMzcNpZ6OkTZhz8gxiGFCsqptUtQZ4CbiiyTZXAE97v34NuEA8jbUKtBCROCAZqAEOOJjVRLlpo3OoOHiUdwrLmvX6vYc9o6Sraup5etowurRNDnBCY4LPyQLRBWg8TLXE+5jPbVS1DtgPdMBTLA4DZcA24K+qWulgVhPlzunVkZ5pLZkxb/MprxVxpKaeaU/nU7L3CE/clEffDBslbSKDkwXCV7eNpr95X7fNMKAe6AzkAD8Ske7H7UDkVhEpEJGCioqK081ropiIMHV0Nqt2HKBg616/X+cZJb2UFdv38c/rzmR4dxslbSKHkwWiBMhsdL8rUPp123ibk9oAlcD1wBxVrVXVXcA8IK/pDlT1MVXNU9W81NRUB/4LJppcObgrbZLj/R44p6r87M2VfLR2F/dcMYDxA2yUtIksThaIfKCXiOSISAJwHTCryTazgMnerycCH6vn/H4bcL54tABGAGsdzGoMyQmxTBqWxZxV5ZTsrTrp9ve9v55XCkr4/gW9uHFEtyAkNCa4HCsQ3msK04G5wBrgFVUtEpF7RORy72ZPAh1EpBj4X+BYV9gHgZbAKjyFZqaqFjqV1ZhjbhrZDRHhmQVbT7jd0/O38MAnxUwalskPL+wVpHTGBJeEyuLtpysvL08LCgrcjmEiwHdfWMp/1lew4O4LaJF4/Gpv7xSWMf3FpVzQN51HbrSBcCa8icgSVT2uCR9sJLUxx5k2OocD1XW8sbTkuOcWbNzDD19ezpCsdjxw/WArDiai2dFtTBNnZbVlUNc2zJy/hYZGa0WsLj3Arc8U0K1DCk9MziMp3kZJm8hmBcKYJkSEaWfnsKniMJ9t8HSf3l5ZxeSZi2mZFMfT04bRNsVGSZvIZwXCGB8uGdCJtFaJzJy3hT2HjjJ5xmKO1npGSXe2UdImSliBMMaHhLgYbhrZjc/XVzDp8YXs2HeEGVOG0ju9ldvRjAkaKxDGfI1Jw7JIiIuheNch/jVpMHnZ7d2OZExQHd+HzxgDQIeWidx39SCS42O5sH+623GMCTorEMacwIRBnd2OYIxrrInJGGOMT1YgjDHG+GQFwhhjjE9WIIwxxvhkBcIYY4xPViCMMcb4ZAXCGGOMT1YgjDHG+BQxCwaJSAVw4mXATqwjsDtAccI5A1iOpizHV4VCjlDIAJGRo5uqpvp6ImIKxOkSkYKvW1UpmjJYDssRDjlCIUM05LAmJmOMMT5ZgTDGGOOTFYgvPeZ2AEIjA1iOpizHV4VCjlDIABGew65BGGOM8cnOIFwkIuJ2BhOa7NgwoSBqCoSIhMRakSLSS0RGA6iLp28i0satfTfK0ElE4kMghx0bX83h+rEBIXV8uL4IuYh0F5E+wd5vxBcIEWkhIg8Ar4vI9SKS41KOBBF5CJgNdBaRRJdytBSRvwFviMgPRORMFzK08GaYCzwoIpd5Hw/qp2Y7No7L4fqx4c0RKsdHS+/x8YSIjHejcIpIkvfYmAvkiEhCMPcf8QUCuAdoDfweGAzc61KOi4A0Ve2jqq+q6tFgB/D+wr8P1AC/xjO45s5g5wD+DLQELgBWABPBlU/Ndmx4hdCxAaFzfNwPJAJvAJOAu4K8f4BrgA6q2ktV56hqTTB3HpEFQkTivP+2BFoBf1TVz4E/ADEi8otg5vBKBRZ6H79YRMaKSKb3frB+DvuBh1X1LlX9AvgPUO/9xOb4pzMRiRGRtnj++PxdVSuAdsBCEWlxbBuHM9ix4ZurxwaEzPEh3n87Ap2BH6rq68DfgE4i8h0n998kSwyQATznvT9WRIaISLtgZYioAiEifUVkJnCPiHRT1UN4DrDrAVR1H/AnYKKIZAQrh/fhzkC6iEzB88focuA9EclU1QYnfgm9bdo/PXZfVTcDbzbapAroraqHnfp01jiDqjZ4fwZHgB+LyCJgCp5P7/Mc/l7YsfHVHK4fG01zhMDx8QjwfRFpraq7gQbgWEFYi+f7c6mItA/0/htnEJH/8WZoAHoD54jId/Ecn3cCz4pIJycyHEdVI+IGdAAWAD/yfiOfBy4EegLrgFTvdgl4Th1vDlKO54CLgXSgEngEiPVuez/wb4dyXA9sByqAW72PxTbZZjLwTwd/Jsdl8D6eBAwAXmz02P3ALDs2ouPYCLHjIwcoAH4CzPAeH2cC5wJzgHaNtrsfuDAIGV7AUxx6ACXHfhZ4mrz+Djzk5M/m2C2SziD6AlWqeh9wN/AecC0Qi6fy/x1APW149XgOymDkmOPNUY/n4DqbL8/cZgKl4kxPjRI8v+SXA7eLSIqq1ovHsf3nAEsBROSKRp9oHcsAoKrVQBc8nxSPeQYod+ginB0bXxUKx4bPHODa8bFbVf8C3IbnQ8M3gWo810Du9ubaDGQDh4OQYS2e780hYBZwjjfDUTzNf+UOZDhOJBWIpUCiiAxRz6nZPDyfTr4J/AYYISK3i8g4YAye08dg5piK52JoBXCziFwFPAysU9XaQIdQT7v6f1R1AbASz/cAIMabC2AgkCkis4AbgbogZQD4GLhGRK4TkQuAf+H5XjhxEc6OjUZC4dg4SQ4I7vGxCqgWkb7e7/d7QAqeT/CPAd8UkStFZASe60VOXJNpmuFdIBnP8fgjoL2IfMv7vfgxsMOBDMcJuwIhIrFf81Q8nm/qt+C/1b4Q6OT9RDIZzzf8t8D9qjo7iDmWAZ29v3zTgb142lb/qar3O5SDRn9c/gJcIiJnqGq993Ud8Rx8lwDPq+rVqtqsg+5UMzR6/NvASDzt7v/0frJuNhFp3eT+sV/kYB8bp5LDyWOj9dc9F6xjozk5Gj0e6OOjbePrF42+TgTW4DmDQ1XzgTKgu6puBH4KDAMex3Mhf34QMhTg+fBwhqoeAW4COgG/BP6hqk82N8MpCUY7VqBueLq//Qxvm6CP5y8EngQu9d7vjaddLykEcuQHO0eTbe8BnvR+Pcz77xQ3M+D5xBqo78UvvT/re4FrvI/FNno+WMdGc3I4cWz4yuHz++3UsXG6OQJ8fPwCT3PR34BpPn4u3wHuA0Z4748AVgX4Z9KcDCsDmeFUb2FxBiEiKSJyD5722kF4ejX4kg98BvxOPN0EB+Kpwi1DIEeJCzka+x1whYgcAiaISIyqPuVihm/guQZwWkQkQ0ReAnrhaaopBH4oIh3U065+7Bh3+tg4nRyBPDZOlOPrms4CemwEKEegjo9OIvIcnjb+q/G0308TkeQmP5e5eNr1fyWeLtDZwKJj10VczLA4EBmazc3q5EfFbe39Nw7PL1ILPIN4fgtknuB1vwSexdOuOTKac+BpL03Fc6ErHzg73DM0ydEauL7R42l4LvAOCvLPJOxyhMrPxeEcKUBuo8en4TmbSTq27yY5/gK8heeawLBwz3Da30c3d36Cb2w7PO197+EZSdi50XN9vb9YVwLxTQ+0Rl+nRHuORtskAOPDPYOPHNfyZRfVGO+/HfFcDO4YxJ9J2OUIlZ+LwzmuAbp4H08Cbsdz1vgc8G/gHO9zcY1/Pseyh3OGQN1CtYnpXjxd//6Mpx3uz8eeUNW1wBLgPDynrzR6Tht9XRXtOcBzEUxVa1R1TgRkaJpjOF92UT3WbNER2KGegU7/5fDPJOxyQGj8XIKQ40/eHNVAvqpmquqNeP54P+J97r89tNTjdLs5h0KGgAi5AiGemTXjgf9T1U/wdP9rIyL/02iz5/E0ceSKyFRv90TL4SNH4z9I4ZzhFHJk4+mBgohMEO/sqIEUKTlC5efiYI4/eHP80LvJ0kabzwGWS4Bn8g2FDIEUEgWicbcvVT0IdAOu8t6vBP4K3HSsu5y3uu7A00f5LjwTjFmOAOYIhQzNyYFn9GuSiDyJZ1RqQMYRWI6wznGjeKauUO9rsoEHgO3e14R9Bse41baFp9/5HUCrRo8dm2bgbKAIaKFftt09DEzy3j8T2IpnIi3LEaAcoZDhNHLc4L0/C9gI3G45LEejHNfh6RX1Gzw9qr4b7hmCcXNnp18OJV8HDG30eAxfLoP6LJ5BKceeewC4yPt1SwLQb9xyhFaG08xxsffrbx37xbQclsNHjlGcZueAUMgQrFvwduS5Mt8dz7TGL+IZqfke3m5vfPUqfhaebnJb8IwqvRTPRdALLEfgcoRChgDmuMhyWA6ncoRCBjduwdmJt+sjnq5sFzd6/Ck8Uxscu9/V+83/t/f+sXlHFgBXWY7A5QiFDJbDcoRDjlDI4Nbt2OmQI8SzKMq9eK7qv6Oq7zd6vAHPHDi9gd+qarV4Jinrqap/shzO5AiFDJbDcoRDjlDI4La4k2/SPN4r+//Ec6r1HvATEekFPKHeJRVFRPFMRlUNoJ6Vm469Pla9k4dZjsDkCIUMlsNyhEOOUMgQEpw6NcHzjZ2P9yo/MA74B3Bjo21SgM14h6Hz5QUesRyBzxEKGSyH5QiHHKGQIRRujo2DUNUDfHmRBjxz3y8DRsqXSzrGAx/iWXIR9X53j/1rOQKbIxQyWA7LEQ45QiFDKHB6oNybwJki0kk9awAXAkfxzGuOqu73fr3PcgQtRyhksByWIxxyhEIGVzldIL4A9uCtwqq6FM8878mNtpmongU6LEdwcoRCBsthOcIhRyhkcJWjBUJVy/BMW3uJiFztHV5eTaPlC9V7gcdyBCdHKGSwHJYjHHKEQgbXBepixolueJYunIFn9OH0YOzTcoR+BsthOcIhRyhkcOvm6DiIxkQkHs/1m4Avfm45wjeD5bAc4ZAjFDK4IWgFwhhjTHgJiem+jTHGhB4rEMYYY3yyAmGMMcYnKxDGGGN8sgJhjDHGJysQxjhIRNqKyJ1u5zCmOaxAGOOstoAVCBOWrEAY46x7gR4islxE/uJ2GGNOhQ2UM8ZB3vl7ZqvqAJejGHPK7AzCGGOMT1YgjDHG+GQFwhhnHQRauR3CmOawAmGMg1R1DzBPRFbZRWoTbuwitTHGGJ/sDMIYY4xPViCMMcb4ZAXCGGOMT1YgjDHG+GQFwhhjjE9WIIwxxvhkBcIYY4xPViCMMcb49P8By0rQkkIV/jsAAAAASUVORK5CYII=\n",
+      "text/plain": [
+       "<Figure size 432x288 with 1 Axes>"
+      ]
+     },
+     "metadata": {
+      "needs_background": "light"
+     },
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "_ = mean_data.plot()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Note that the plot's $x$-axis is labeled appropriately, i.e, with the date and time only."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "The data can be indexed by a string representing a timestamp."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 67,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "<xarray.DataArray (x: 5, y: 7)>\n",
+       "array([[ 0.134522,  0.139882, -0.783935,  0.527992,  0.083225,  1.209003,\n",
+       "         0.298935],\n",
+       "       [-1.443417,  0.726843,  0.218782, -0.407327,  0.174149,  1.049454,\n",
+       "        -1.040939],\n",
+       "       [-2.765147,  0.304767,  0.215509, -0.338329, -0.321164, -1.759763,\n",
+       "         1.325458],\n",
+       "       [ 1.215391, -0.014276,  1.304747, -1.2291  ,  1.705403,  0.70838 ,\n",
+       "        -0.539714],\n",
+       "       [ 0.60679 ,  0.672704,  0.441869, -0.112825,  0.324842,  1.150895,\n",
+       "        -0.648897]])\n",
+       "Coordinates:\n",
+       "  * x        (x) float64 -2.0 -1.0 0.0 1.0 2.0\n",
+       "  * y        (y) float64 -3.0 -2.0 -1.0 0.0 1.0 2.0 3.0\n",
+       "    t        datetime64[ns] 2019-07-02T06:00:00"
+      ]
+     },
+     "execution_count": 67,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "data.sel(t='2019-07-02 06:00:00')"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "When indexing with a data, all data for that date is returned."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 68,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "<xarray.DataArray 't' (t: 4)>\n",
+       "array(['2019-07-02T00:00:00.000000000', '2019-07-02T06:00:00.000000000',\n",
+       "       '2019-07-02T12:00:00.000000000', '2019-07-02T18:00:00.000000000'],\n",
+       "      dtype='datetime64[ns]')\n",
+       "Coordinates:\n",
+       "  * t        (t) datetime64[ns] 2019-07-02 ... 2019-07-02T18:00:00"
+      ]
+     },
+     "execution_count": 68,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "data.sel(t='2019-07-02').coords['t']"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "The data can also be sliced along the time coordinate."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 69,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "<xarray.DataArray 't' (t: 3)>\n",
+       "array(['2019-07-02T06:00:00.000000000', '2019-07-02T12:00:00.000000000',\n",
+       "       '2019-07-02T18:00:00.000000000'], dtype='datetime64[ns]')\n",
+       "Coordinates:\n",
+       "  * t        (t) datetime64[ns] 2019-07-02T06:00:00 ... 2019-07-02T18:00:00"
+      ]
+     },
+     "execution_count": 69,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "data.sel(t=slice('2019-07-02 02:00:00', '2019-07-02 20:00:00')).coords['t']"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Plotting the values at some point in time is now easy."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 70,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAW8AAAEWCAYAAACpERYdAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjAsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+17YcXAAAV8ElEQVR4nO3de7BlZX3m8e9zGhovgKhNQLkISRgjOiqGmEx5GTISbc2F8TajsRxHrOpQM44YxwRHpyZOEpOoU9bM6NRIz4i3MhrHS2lVjHcTtBIMaBBBvBAVxRsBg4Cg0H1+88debW1O79vh7HPWejnfT9VbfdZee7/rd3Z3P+c973rX2qkqJEltWem7AEnS+hnektQgw1uSGmR4S1KDDG9JapDhLUkNMrwlqUGG90Al+XqSMzeh319N8qkkNyT5bpL/k+SIsf2HJbkgyY3d/heN7duZ5F1dbZXkjDV9H5XkzUmu7drL59SSJK9Mcn3XXpUk3b7HJLl5TaskT53R38OTfCbJLd2fDx/b9ztJLk9yU5KvJfmd7vETJxzjh2Pbj5lVZ9fHjiR/mOTbXf9/l+SoGXX+dvfe/qB7rw8b23dSkk9038MX5/0bWGZfakxV2QbYgK8DZ25Cv78J7AbuAdwb+Avg9WP7/xj4ZLfvQcB3gd3dvp3AC4FHA98BzljT9xuB/9f1fRLw98BzZ9TyW8CXgOOB44AvAOdMee4ZwE3APafs3wlcDfw2cBjwgm57Z7f/d4FHAIcAD+z2PWNCPwX87HrqBP4Q+DjwACDAQ4C7TanzCcD3gAd37/FfAn8ytv9vgNcAdweeCtwAHL3Zfdnaa70XYJvwlwJvBVaBW4Gbgd/dxGM9Bfj82Pa3gMePbf8B8I4Jr7tmQnhfB/zC2PZLgU/OOPZfA3vGtp8HXDTluW8E3jijr8d3tWfssW8c+MEz4fn/E3jthMcnhffUOrvQvBn4mQXf7z8F/mhs+3HAd7uv/wnwY+CIsf2fZPoPtKX1ZWuvOW0yQFX1bEbB8+tVdXhVvWrtc7pf92+Y0X5zwcM9Frii6/PewP2Bz43t/xyjkd2isubrh8x47oMXOVaSewBPA948p6/LqkupzmVT+gvwGLrvewGz6vynwD7gad30xZeT/PuxYz06yQ1z+jomyX27fV+tqpsmHWuZfal9h/RdgO6cqvoGMHVedRFJfgV4DvCL3UOHd3/+YOxpPwCOYDEfBF6S5DnAMcDZjKZQpjl8wrEOT5I1IfxURqP6v1pHX7Nqfzmj8z1vnNHfQnUymkq5F6OR7snAKcDHkny5qj5SVZ/ijn9Pk/qiq3Pa93AcwDL7UvsceW9TSX6J0a/dT6uqL3cP39z9eeTYU49kNNe8iBcwmur5CvA+4O2MpldI8tKxk4CvHzve2mPdvCa4YfQD5i3jj685yXjihL4m1p7k+cC/AX61qn684Pc1q85bu8d+v6purarLgHcAT1pHX3R1LvQ9bFJfaozhPVwzb/c4YZXE2vasGa89DXg/cHZVfewnB6z6R0YnIh829vSHseD0QlV9v6qeVVXHVtWDGf37+ttu3x91U0CHV9U53UuumHesJCcwOln5ljXHOnysfaN73UPHV4EADx3vL8nZwEuAx1XVNYt8TwvUedmBkjbQ1/eq6vpu309nbPUPs9//Zfal1vQ96W6b3ICLGDtJtsR+H8JohcK/nrL/TxhNT9wb+DlGYb57bP9hwN0Yjagf332dbt/PAPcFdgBPZDTV8eAZtZwDXMnoV/n7MwqWc9Y856XAhQt8XwdWm5zb1fh87rja5FmMVs48aE4/k05YzqwTuBA4vzvug4BrGf2AmNT/7q6OU7v3+OPccYXIRcB/697XJzN7tcnS+rK113ovwDblLwbOYnTS8gbgxUvs942MVrLcPNauGNt/GHABcGMX8i9a8/qvdwE33k7q9v0r4NvALcClwBPm1BLgVcD3u/YqxlaLdM/5IvC8Bb+304DPMJrK+Cxw2ti+rwG3r/m+Xz+hj0nhPbPOLtQ/2PX5VeC3xvY9htEUy3h/L+re2xu7v4/DxvadxGjJ362MlieeuRl92dpvB0ZMkqSGOOctSQ0yvCWpQYa3JDXI8JakBjV1heWue9+rTjru2L7LOEitDvOkbw45tO8SJtp/yGHzn9STlf23913CRKs/uL7vEia69cif6ruEqb70+c9dV1VHb6SPE3L3+hGrc593Hbd9qKp2b+RY69VUeJ903LF8+p3n913GQerHP+q7hIlyn/v1XcJEN933lL5LmOrwm77VdwkT3fLBt/ZdwkSX//K5fZcw1aNO3nX1Rvv4Eas8lfn/j87n6l0bPdZ6NRXekrSVAuzI3Kctfn3tEhnekjRFgJ0rC6T3/k0v5SCGtyRNMRp5LzL03nqGtyRNkwWnTXpgeEvSFI68JalBC5+w7IHhLUlTxZG3JLUmwKGGtyS1JZ6wlKQ2OW0iSY3xhKUkNcilgpLUoGTBy+N7YHhL0gxOm0hSY5zzlqQGxYt0JKlNQx159/YZlklOSPKJJFcmuSLJcD+SQ9K2NLpIJ3NbH/ocee8D/mNVfTbJEcBnknykqr7QY02S9BMLfxhDD3oL76r6DvCd7uubklwJHAcY3pIGwROWcyQ5CTgN+PSEfXuAPQAn3u+YLa1LkoZ6wrK3Oe8DkhwOvBt4YVXduHZ/Ve2tqtOr6vSj73OvrS9Q0raVwEoyt/Wh15F3kkMZBffbquo9fdYiSQcLGei8SW/hnSTAG4Arq+o1fdUhSdMksGPnjr7LmKjPaZNHAc8G/kWSS7v2pB7rkaQ7CmRH5rY+9Lna5FOMTuZK0jAlrCwhnJOcALwFOBZYBfZW1f/YSJ+DWG0iSUOVlaVMUCz9uhbDW5KmSFjKyHszrmsxvCVphgXntHcluWRse29V7Z3Y34zrWtbD8JakKZIsutrkuqo6fYH+Zl7Xsh6GtyRNE8iS7m2y7OtaDG9Jmiqs7Nj4CcvNuK6l98vjJWmwlrfOe+nXtTjylqQpkoVPWM60Gde1GN6SNMMypk02g+EtSVMkYcehhrcktSUQR96S1J5lXGG5GQxvSZom3s9bkpoTp00kqUHBE5aS1Jos6QrLzdBUeO+/6UZu/KsP9l3GQe723Jf3XcJEN73uvL5LmOj1D/t3fZcw1VPe9KK+S5jo5140zPfsiMOaipD1W9JFOpvhLv7OS9IGOOctSS3Ksj5JZ+kMb0maYvRJOoa3JLUlYWXnMGNymFVJ0iA4bSJJ7Qlkx0Ifg7blDG9JmiLE1SaS1JzAitMmktQeR96S1JgkrBw6zJgcZlWSNARxzluS2uPl8ZLUJq+wlKTGJF6kI0nt8fJ4SWqTI29JakwSVgZ6eXyvP1KSXJDk2iSX91mHJE2THStzWx/6/n3gTcDunmuQpMky3PDuddqkqi5MclKfNUjSdK42kaTmZMXVJndakj3AHoDj73Nkz9VI2m6GOvIeZlVjqmpvVZ1eVafvOvwefZcjaTtJyMqOuW2xrpa7QGPw4S1JvVrZMb8t5k0scYFG30sF3w78DfDAJNckeV6f9UjSHQVWVua3BVTVhcD3l1VZ36tNntnn8SVppsU/w3JXkkvGtvdW1d5Nqgpo4ISlJPUmgUN2LvLM66rq9M0uZ5zhLUlTxHXektSgsJ4TkltqmD9SJGkQsrTVJsteoOHIW5JmWNa0ybIXaBjekjRNVhY9YbnlDG9JmmbxpYJbzvCWpKmy8EU4W83wlqRpBrzaxPCWpKmy8I2ntprhLUmzOG0iSY3JCnG1iSQ1JjjylqTWhLhUUJKa42oTSWpRDG9Jak5CDjm07yomaiq8P/cPt3PM3mv7LuMgP3zyt/ouYaKjzj6v7xImek4d2XcJU+Xn/6zvEib65Tdc3HcJE72r/nPfJWy+eMJSkhoTw1uSWlSGtyQ1JjjylqT2ZPQhxANkeEvSFAXUjmHG5DCrkqQhiCcsJalNhrcktcaRtyQ1yaWCktQiw1uSGhNvTCVJTXLaRJKaEz9JR5Ka4+XxktQilwpKUpNqZZgxOcyqJGkIBnx5fK9VJdmd5EtJrkrykj5rkaSJkvltoW6Wm3e9hXeSHcD/Ap4InAo8M8mpfdUjSQfrRt7z2rxeNiHv5h510gGSnLGRg3YeCVxVVV+tqtuAdwBnLaFfSVqaysrctoCl590iR31nkvMycvckrwX+eCMH7RwHfHNs+5rusTtIsifJJUkuqX0/WsJhJWkdFht57zqQU13bs6aXhfJuPRY5YfmLwCuBvwaOAN4GPGojB+1Mmiiqgx6o2gvsBVi5x66D9kvSZinC6sSoOsh1VXX6jP0L5d16LBLetwO3AncH7gZ8rapWN3LQzjXACWPbxwPfXkK/krQkxWotZcy49LxbZNrkYkbh/QvAoxlNtL9rIwcd6/eUJCcn2Qk8A3j/EvqVpKWpBdoClp53i4y8n1dVl3Rffxc4K8mzN3JQgKral+T5wIeAHcAFVXXFRvuVpGUpYHUJA+/NyLu54T0W3OOPvXUjBx3r5wPAB5bRlyRthlrOtMnS884rLCVpimWNvDeD4S1J0xTsN7wlqT3LmjZZNsNbkqYoYBnrojeD4S1JMwx04G14S9IsnrCUpMZUwf6BDr0Nb0maYaDZbXhL0jSjdd7DTG/DW5JmGGZ0G96SNJMnLCWpQQOdNTG8JWmaqnK1iSS1yGkTSWpM4bSJJDVpdaDrTZoK7/sc+1Ocdd5/6LuMg31zoB8AdPIj+q5gotuHOpQBTjzkh32XMNGHTrq47xImeuuJL+67hBlet5RehvrPtanwlqSt5EU6ktSgKrh9oJ/GYHhL0lQuFZSk5jhtIkktKtg/0I/SMbwlaQpH3pLUoAJuH+glloa3JE1TsN/wlqS2FOW0iSS1aKDLvA1vSZrGE5aS1CLnvCWpPUNebbLSdwGSNFQHpk3mtY1K8vQkVyRZTXL6Iq8xvCVpmipWV+e3JbgceApw4aIvcNpEkqYotma1SVVdCZBk4dcY3pI0w4LTIruSXDK2vbeq9m5SSUBP4Z3k6cDLgQcBj6yqS2a/QpK23uh+3gvdmeq6qpo5V53ko8CxE3a9rKret97a+hp5H5jfOb+n40vSXMucNqmqM5fT00gv4X1n5nckqQ9DvUjH1SaSNEV1n6Qzr21UkicnuQb4Z8CfJ/nQvNds2sh7WfM7SfYAewDuuWtSd5K0SbboCsuqei/w3vW8ZtPCe1nzO90Z270Au3761GH+/iLpLqnw8nhJak4V3LZvmJ+D1suc952Z35GkrVYU+1fntz70tdpk3fM7krTlvKugJLXHOW9JalA58pakNhnektSY1Sp+PNDVJoa3JM3gyFuSGuOctyQ1ahn3LtkMhrckTXHgIp0hMrwlaYohXx5veEvSFKOLdAxvSWpLOW0iSc3x8nhJalAV7DO8JaktjrwlqUFV5WoTSWqRI29JaoyXxy/JA+61k//9xBP6LuMgxfBqAvjYd/b3XcJETzj0yr5LmOr2Yx7YdwkT3faPN/RdwkRnP3aYUwoA5yypnzK8JaktVbBqeEtSa4ryxlSS1JiC/a42kaS2FFDDzG7DW5JmcdpEklrjCUtJalG5VFCSWlMF+/cPc9Lb8JakGYY68l7puwBJGrJarblto5K8OskXk1yW5L1Jjpr3GsNbkqaoKlZX57cl+AjwkKp6KPBl4D/Ne4HhLUkzVNXctoRjfLiq9nWbFwHHz3uNc96SNMOCF+nsSnLJ2Pbeqtp7Jw95NvBn855keEvSFLX45fHXVdXps56Q5KPAsRN2vayq3tc952XAPuBt8w5oeEvSNLW81SZVdeas/UmeA/wa8LhaYC7G8JakqYrVLbg8Pslu4Dzgn1fVLYu8xvCWpClGN6baknXerwMOAz6SBOCiqpr5eRK9hHeSVwO/DtwG/D3w3Koa5keFSNq+ljhtMvMwVT+73tf0tVRw3WsaJakPW7TOe916GXlX1YfHNi8CntZHHZI0S1Wx6r1Nppq5pjHJHmAPwIknzF23LklLte1uCbusNY3dQve9AD9/2sOH+S5Kusuq1f19lzDRpoX3stc0StKWq9p+4T3LnVnTKElbrTC811r3mkZJ2nJVrN5+W99VTNTXapN1r2mUpC3ntIkktcnwlqTGOOctSS0qR96S1KBi1fCWpLZUFav7XG0iSW2povY78pak5jjnLUmtcZ23JLXI8Jak5ow+Bs37eUtSW1xtIkkNKtd5S1JzClwqKEnNcbWJJLXI8Jak9gz4hGVa+vjIJP8AXL2k7nYB1y2pr2Uaal0w3Nqsa32GWhcst7YHVNXRG+kgyQcZ1TTPdVW1eyPHWq+mwnuZklxSVaf3XcdaQ60Lhlubda3PUOuCYdc2NCt9FyBJWj/DW5IatJ3De2/fBUwx1LpguLVZ1/oMtS4Ydm2Dsm3nvCWpZdt55C1JzTK8JalB2zq8k/xBksuSXJrkw0nu33dNAEleneSLXW3vTXJU3zUBJHl6kiuSrCbpfTlXkt1JvpTkqiQv6bueA5JckOTaJJf3Xcu4JCck+USSK7u/x3P7rgkgyd2S/G2Sz3V1/de+a2rBtp7zTnJkVd3Yff0C4NSqOqfnskjyeODjVbUvySsBquq8nssiyYOAVeB84MVVdUmPtewAvgz8CnANcDHwzKr6Ql81HZDkscDNwFuq6iF913NAkvsB96uqzyY5AvgM8C/7fs+SBLhnVd2c5FDgU8C5VXVRn3UN3bYeeR8I7s49Gd1ErHdV9eGq2tdtXgQc32c9B1TVlVX1pb7r6DwSuKqqvlpVtwHvAM7quSYAqupC4Pt917FWVX2nqj7bfX0TcCVwXL9VQY3c3G0e2rVB/F8csm0d3gBJXpHkm8CzgP/Sdz0TnA38Rd9FDNBxwDfHtq9hAEHUiiQnAacBn+63kpEkO5JcClwLfKSqBlHXkN3lwzvJR5NcPqGdBVBVL6uqE4C3Ac8fSl3dc14G7OtqG0xdA5EJjzlaW0CSw4F3Ay9c89tnb6pqf1U9nNFvmY9MMpjppqG6y99VsKrOXPCpfwr8OfB7m1jOT8yrK8lzgF8DHldbeGJiHe9X364BThjbPh74dk+1NKObU3438Laqek/f9axVVTck+UtgNzCoE75Dc5cfec+S5JSxzd8AvthXLeOS7AbOA36jqm7pu56Buhg4JcnJSXYCzwDe33NNg9adGHwDcGVVvabveg5IcvSBFVVJ7g6cyUD+Lw7Zdl9t8m7ggYxWUFwNnFNV3+q3KkhyFXAYcH330EUDWQXzZOC1wNHADcClVfWEHut5EvDfgR3ABVX1ir5qGZfk7cAZjG4l+j3g96rqDb0WBSR5NPBJ4POM/s0DvLSqPtBfVZDkocCbGf09rgDvrKrf77OmFmzr8JakVm3raRNJapXhLUkNMrwlqUGGtyQ1yPCWpAYZ3pLUIMNbkhpkeKtJ3b3Yzx3bfkV3W19pW/AiHTWpuyvee6rqEUlWgK8Aj6yq62e+ULqLuMvfmEp3TVX19STXJzkNOAb4O4Nb24nhrZb9X+DfAscCF/RbirS1nDZRs7q7CX6e0SevnFJV+3suSdoyjrzVrKq6LckngBsMbm03hrea1Z2o/CXg6X3XIm01lwqqSUlOBa4CPlZVX+m7HmmrOectSQ1y5C1JDTK8JalBhrckNcjwlqQGGd6S1KD/D7sCkRm2RDa/AAAAAElFTkSuQmCC\n",
+      "text/plain": [
+       "<Figure size 432x288 with 2 Axes>"
+      ]
+     },
+     "metadata": {
+      "needs_background": "light"
+     },
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "_ = data.sel(t='2019-07-02 06:00:00').plot()"
+   ]
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3",
+   "language": "python",
+   "name": "python3"
+  },
+  "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.7.3"
+  },
+  "toc-autonumbering": false,
+  "toc-showcode": false,
+  "toc-showmarkdowntxt": false
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}

From 27b0709f75279a0ccff741f6c0140ef4818dfc4d Mon Sep 17 00:00:00 2001
From: Geert Jan Bex <geertjan.bex@uhasselt.be>
Date: Mon, 20 Jan 2020 09:55:47 +0100
Subject: [PATCH 4/6] Add networkx examples

---
 source-code/README.md                         |   5 +-
 source-code/networkx/README.md                |  22 ++
 .../networkx/add_random_edge_weights.py       |  47 +++
 .../networkx/compute_leaf_path_lengths.py     |  35 +++
 source-code/networkx/generate_random_tree.py  |  58 ++++
 source-code/networkx/graph.txt                |   6 +
 source-code/networkx/graph.xml                |  30 ++
 source-code/networkx/max_flow.py              |  47 +++
 .../networkx/par_compute_leaf_lengths.py      |  45 +++
 source-code/networkx/shortest_path.ipynb      | 269 ++++++++++++++++++
 source-code/networkx/topo_sort.ipynb          | 183 ++++++++++++
 source-code/networkx/topo_sort.py             | 116 ++++++++
 source-code/networkx/weighted_tree.xml        |  39 +++
 13 files changed, 901 insertions(+), 1 deletion(-)
 create mode 100644 source-code/networkx/README.md
 create mode 100755 source-code/networkx/add_random_edge_weights.py
 create mode 100755 source-code/networkx/compute_leaf_path_lengths.py
 create mode 100755 source-code/networkx/generate_random_tree.py
 create mode 100644 source-code/networkx/graph.txt
 create mode 100644 source-code/networkx/graph.xml
 create mode 100755 source-code/networkx/max_flow.py
 create mode 100755 source-code/networkx/par_compute_leaf_lengths.py
 create mode 100644 source-code/networkx/shortest_path.ipynb
 create mode 100644 source-code/networkx/topo_sort.ipynb
 create mode 100755 source-code/networkx/topo_sort.py
 create mode 100644 source-code/networkx/weighted_tree.xml

diff --git a/source-code/README.md b/source-code/README.md
index 60fefd6..a1768bf 100644
--- a/source-code/README.md
+++ b/source-code/README.md
@@ -20,6 +20,7 @@ to create it.  There is some material not covered in the presentation as well.
   * networkx
   * jupyter
   * folium (with conda, use `-c conda-forge`)
+  * xarray
 
 ## What is it?
 * [`db-access`](db-access): illustration of accessing SQLite databases and using
@@ -27,10 +28,12 @@ to create it.  There is some material not covered in the presentation as well.
 * [`gis`](gis): illustrations of working with geospatial data, including geopandas.
 * [`holoviews`](holoviews): illustrations of using HoloViews for convenient
   visualizations.
+* [`networkx`](networkx): illustration of using the networkx library for graph
+  representation and algorithms.
 * [`pandas`](pandas): illustrations of using pandas and seaborn.
 * [`regexes`](regexes): illustrations of using regular expressions for validation
   and information extraction from textual data.
-* [1seaborn`]:(seaborn): illustrations of using Seaborn to create plots.
+* [`seaborn`](seaborn): illustrations of using Seaborn to create plots.
 * [`web-scraping`](web-scraping): illustration of web scraping using beautiful soup
   and graph representation using networkx.
 * [`xarray`](xarray): illustrates the xarray library for pandas-like operations
diff --git a/source-code/networkx/README.md b/source-code/networkx/README.md
new file mode 100644
index 0000000..573fcea
--- /dev/null
+++ b/source-code/networkx/README.md
@@ -0,0 +1,22 @@
+# NetworkX
+NetworkX is an excellent library that implements graph representations
+and algorithms.  Note is is not part of Python's standard library.
+
+## What is it?
+1. `generate_random_tree.py`: illustration of how to use the NetworkX
+   DiGraph class to represent a tree, generates a random tree according
+   to specifications
+1. `add_random_weights.py`: reads a GraphML representation of a tree, and
+   addds random weights to the edges
+1. `compute_leaf_path_length.py`: compute the length of all paths from the
+   tree's root to each of the leaves
+1. `par_compute_leaf_length.py`: compute the length of all paths
+   from the tree's root to each of the leaves, uses `multiprocessing` for
+   parallel processing
+1. `graph.xml`: example GraphML representation of a tree
+1. `graph.txt`: example edge list representation of a tree
+1. `weighted_tree.xml`: example GraphML representation of a weighted tree
+1. `max_flow.py`: illustration of the maximum flow algorithm on a very
+    simple case of three parallel flows.
+1. `shortest_path.ipynb`: Jupyter notebook illustrating the shortest path
+    algorithm.
diff --git a/source-code/networkx/add_random_edge_weights.py b/source-code/networkx/add_random_edge_weights.py
new file mode 100755
index 0000000..496a818
--- /dev/null
+++ b/source-code/networkx/add_random_edge_weights.py
@@ -0,0 +1,47 @@
+#!/usr/bin/env python
+
+from argparse import ArgumentParser
+import random
+import sys
+import networkx as nx
+
+
+def add_edge_weights(tree):
+    _add_edge_weights(tree, '1')
+
+
+def _add_edge_weights(tree, node):
+    for child in tree.neighbors_iter(node):
+        tree[node][child]['weight'] = random.random()
+        _add_edge_weights(tree, child)
+
+
+def main():
+    arg_parser = ArgumentParser(description='add edge weights to tree')
+    arg_parser.add_argument('--input', required=True,
+                            help='inpput file')
+    arg_parser.add_argument('--output', required=True,
+                            help='outpput file')
+    arg_parser.add_argument('--seed', type=int, default=None,
+                            help='seed for random number generator')
+    arg_parser.add_argument('--delim', dest='delimiter', default=' ',
+                            help='delimiter for edge list')
+    arg_parser.add_argument('--no-data', action='store_true',
+                            dest='no_data', help='show edge data')
+    arg_parser.add_argument('--edge-list', action='store_true',
+                            help='generate edge list output')
+    options = arg_parser.parse_args()
+    random.seed(options.seed)
+    tree = nx.read_graphml(options.input)
+    add_edge_weights(tree)
+    if options.edge_list:
+        nx.write_edgelist(tree, options.output,
+                          delimiter=options.delimiter,
+                          data=not options.no_data)
+    else:
+        nx.write_graphml(tree, options.output)
+    return 0
+
+if __name__ == '__main__':
+    status = main()
+    sys.exit(status)
diff --git a/source-code/networkx/compute_leaf_path_lengths.py b/source-code/networkx/compute_leaf_path_lengths.py
new file mode 100755
index 0000000..a2417f9
--- /dev/null
+++ b/source-code/networkx/compute_leaf_path_lengths.py
@@ -0,0 +1,35 @@
+#!/usr/bin/env python
+
+from argparse import ArgumentParser
+import sys
+import networkx as nx
+
+
+def is_leaf(tree, node):
+    return len(tree.neighbors(node)) == 0
+
+
+def leaf_path_lengths(tree):
+    path_lengths = nx.shortest_path_length(tree, '1', weight='weight')
+    remove = []
+    for node in path_lengths:
+        if not is_leaf(tree, node):
+            remove.append(node)
+    for node in remove:
+        del path_lengths[node]
+    return path_lengths
+
+
+def main():
+    arg_parser = ArgumentParser(description='compute leaf path lengths')
+    arg_parser.add_argument('--input', required=True, help='input file')
+    options = arg_parser.parse_args()
+    tree = nx.read_graphml(options.input)
+    path_lengths = leaf_path_lengths(tree)
+    for leaf in path_lengths:
+        print('{0}: {1:.4f}'.format(leaf, path_lengths[leaf]))
+    return 0
+
+if __name__ == '__main__':
+    status = main()
+    sys.exit(status)
diff --git a/source-code/networkx/generate_random_tree.py b/source-code/networkx/generate_random_tree.py
new file mode 100755
index 0000000..22388e4
--- /dev/null
+++ b/source-code/networkx/generate_random_tree.py
@@ -0,0 +1,58 @@
+#!/usr/bin/env python
+
+from argparse import ArgumentParser
+import random
+import sys
+import networkx as nx
+
+
+def random_tree(max_branch, max_height):
+    G = nx.DiGraph()
+    random_subtree(G, None, max_branch, max_height)
+    return G
+
+
+def random_subtree(G, root, max_branch, max_height):
+    if max_height:
+        if root:
+            nr_branches = random.randrange(0, max_branch + 1)
+            for i in range(1, nr_branches + 1):
+                node = root + '.' + str(i)
+                G.add_edge(root, node)
+                random_subtree(G, node, max_branch, max_height - 1)
+        else:
+            node = '1'
+            random_subtree(G, node, max_branch, max_height - 1)
+
+
+def main():
+    arg_parser = ArgumentParser(description='generate random tree')
+    arg_parser.add_argument('--output', required=True,
+                            help='output file name')
+    arg_parser.add_argument('--branching', dest='max_branch', type=int,
+                            default=3, help='maximum node branching')
+    arg_parser.add_argument('--height', dest='max_height', type=int,
+                            default=4, help='maximum tree height')
+    arg_parser.add_argument('--seed', type=int, default=None,
+                            help='seed for random number generator')
+    arg_parser.add_argument('--delim', dest='delimiter', default=' ',
+                            help='delimiter for edge list')
+    arg_parser.add_argument('--no-data', action='store_true',
+                            dest='no_data', help='show edge data')
+    arg_parser.add_argument('--edge-list', action='store_true',
+                            dest='edge_list',
+                            help='generate edge list output')
+    options = arg_parser.parse_args()
+    random.seed(options.seed)
+    tree = random_tree(options.max_branch, options.max_height)
+    if options.edge_list:
+        nx.write_edgelist(tree, options.output,
+                          delimiter=options.delimiter,
+                          data=not options.no_data)
+    else:
+        nx.write_graphml(tree, options.output)
+    return 0
+
+if __name__ == '__main__':
+    status = main()
+    sys.exit(status)
diff --git a/source-code/networkx/graph.txt b/source-code/networkx/graph.txt
new file mode 100644
index 0000000..018651b
--- /dev/null
+++ b/source-code/networkx/graph.txt
@@ -0,0 +1,6 @@
+root child1 {'span': 1.3}
+child1 grandchild1 {'span': 0.4}
+root child2 {'span': 0.7}
+child2 grandchild2 {'span': 0.8}
+child2 grandchild3 {'span': 0.2}
+grandchild3 greatgrandchild1 {'span': 0.1}
diff --git a/source-code/networkx/graph.xml b/source-code/networkx/graph.xml
new file mode 100644
index 0000000..1a0effa
--- /dev/null
+++ b/source-code/networkx/graph.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?><graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
+  <key attr.name="span" attr.type="double" for="edge" id="d0" />
+  <graph edgedefault="directed">
+    <node id="child1" />
+    <node id="child2" />
+    <node id="greatgrandchild1" />
+    <node id="grandchild3" />
+    <node id="grandchild2" />
+    <node id="grandchild1" />
+    <node id="root" />
+    <edge source="root" target="child1">
+      <data key="d0">1.3</data>
+    </edge>
+    <edge source="child1" target="grandchild1">
+      <data key="d0">0.4</data>
+    </edge>
+    <edge source="child2" target="grandchild3">
+      <data key="d0">0.2</data>
+    </edge>
+    <edge target="child2" source="root">
+      <data key="d0">0.7</data>
+    </edge>
+    <edge source="child2" target="grandchild2">
+      <data key="d0">0.8</data>
+    </edge>
+    <edge target="greatgrandchild1" source="grandchild3">
+      <data key="d0">0.1</data>
+    </edge>
+  </graph>
+</graphml>
diff --git a/source-code/networkx/max_flow.py b/source-code/networkx/max_flow.py
new file mode 100755
index 0000000..bb6da32
--- /dev/null
+++ b/source-code/networkx/max_flow.py
@@ -0,0 +1,47 @@
+#!/usr/bin/env python
+
+from argparse import ArgumentParser
+import networkx as nx
+import random
+
+
+def create_graph(nr_nodes_per_layer=3):
+    alpha = 3
+    beta = 0.5
+    G = nx.DiGraph()
+    source = 0
+    sink = 2*nr_nodes_per_layer + 1
+    fmt_str = 'capacity {0} -> {1}: {2:.3f}'
+# from source to first layter
+    for i in range(1, nr_nodes_per_layer + 1):
+        capacity = random.gammavariate(alpha, beta)
+        G.add_edge(source, i, capacity=capacity)
+        print(fmt_str.format(source, i, capacity))
+# from layter 1 to layer 2
+    for i in range(1, nr_nodes_per_layer + 1):
+        j = i + nr_nodes_per_layer
+        capacity = random.gammavariate(alpha, beta)
+        G.add_edge(i, j, capacity=capacity)
+        print(fmt_str.format(i, j, capacity))
+# rom layer 2 to sink
+    for i in range(nr_nodes_per_layer + 1, 2*nr_nodes_per_layer + 1):
+        capacity = random.gammavariate(alpha, beta)
+        G.add_edge(i, sink, capacity=capacity)
+        print(fmt_str.format(i, sink, capacity))
+    return G, source, sink
+
+
+def print_flow_dict(G, flow_dict):
+    for edge in G.edges_iter():
+        i, j = edge
+        print('flow {0} -> {1}: {2:.3f}'.format(i, j, flow_dict[i][j]))
+
+if __name__ == '__main__':
+    arg_parser = ArgumentParser(description='experiment with maximum flow '
+                                            'algorithm')
+    arg_parser.add_argument('--n', type=int, help='number of nodes/layer')
+    options = arg_parser.parse_args()
+    G, source, sink = create_graph(options.n)
+    flow_value, flow_dict = nx.maximum_flow(G, source, sink)
+    print('value = {0:.3f}'.format(flow_value))
+    print_flow_dict(G, flow_dict)
diff --git a/source-code/networkx/par_compute_leaf_lengths.py b/source-code/networkx/par_compute_leaf_lengths.py
new file mode 100755
index 0000000..2114dcb
--- /dev/null
+++ b/source-code/networkx/par_compute_leaf_lengths.py
@@ -0,0 +1,45 @@
+#!/usr/bin/env python
+
+from argparse import ArgumentParser
+from multiprocessing import Pool
+import networkx as nx
+
+pool = Pool(processes=2)
+
+
+def _is_leaf(tree, node):
+    return len(tree.neighbors(node)) == 0
+
+
+def _leaf_path_lengths(tree, node):
+    global pool
+    if _is_leaf(tree, node):
+        return {node: 0.0}
+    else:
+        path_lengths = {}
+        results = {}
+        for child in tree.neighbors_iter(node):
+            results[child] = _leaf_path_lengths(tree, child)
+        for child in tree.neighbors_iter(node):
+            weight = tree[node][child]['weight']
+#            lengths = results[child].get()
+            lengths = results[child]
+            for leaf in lengths:
+                path_lengths[leaf] = lengths[leaf] + weight
+        return path_lengths
+
+
+def leaf_path_lengths(tree):
+    return _leaf_path_lengths(tree, '1')
+
+if __name__ == '__main__':
+    arg_parser = ArgumentParser(description='compute leaf path lengths')
+    arg_parser.add_argument('--input', required=True, help='input file')
+    arg_parser.add_argument('--pool-size', default=1,
+                            dest='pool_size', type=int,
+                            help='pool size for parallel processing')
+    options = arg_parser.parse_args()
+    tree = nx.read_graphml(options.input)
+    path_lengths = leaf_path_lengths(tree)
+    for leaf in path_lengths:
+        print('{0}: {1:.4f}'.format(leaf, path_lengths[leaf]))
diff --git a/source-code/networkx/shortest_path.ipynb b/source-code/networkx/shortest_path.ipynb
new file mode 100644
index 0000000..55e4f3a
--- /dev/null
+++ b/source-code/networkx/shortest_path.ipynb
@@ -0,0 +1,269 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Shortest path"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Import libraries."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "import math\n",
+    "import matplotlib.pyplot as plt\n",
+    "import networkx as nx\n",
+    "import random\n",
+    "%matplotlib inline"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "For convenience, seed the random number generator to get something reproducible."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 37,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "random.seed(1214)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Define the cities and their positions."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 48,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "E: (0.666, 0.435)\n",
+      "C: (0.701, 0.188)\n",
+      "A: (0.463, 0.649)\n",
+      "B: (0.589, 0.808)\n",
+      "G: (0.561, 0.333)\n",
+      "F: (0.632, 0.039)\n",
+      "D: (0.914, 0.825)\n"
+     ]
+    }
+   ],
+   "source": [
+    "city_names = ['A', 'B', 'C', 'D', 'E', 'F', 'G']\n",
+    "cities = {}\n",
+    "for name in city_names:\n",
+    "    cities[name] = (random.random(), random.random())\n",
+    "for city, position in cities.items():\n",
+    "    print('{0}: ({1:.3f}, {2:.3f})'.format(city, position[0], position[1]))"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Define the road network between the cities."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 41,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "roads = [\n",
+    "    ('A', 'B'),\n",
+    "    ('A', 'D'),\n",
+    "    ('A', 'E'),\n",
+    "    ('B', 'C'),\n",
+    "    ('C', 'D'),\n",
+    "    ('C', 'E'),\n",
+    "]"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Define a function to compute the distance between two given cities based on their positions."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 49,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "def distance(city1, city2, cities):\n",
+    "    return math.sqrt((cities[city1][0] - cities[city2][0])**2 +\n",
+    "                     (cities[city1][1] - cities[city2][1])**2)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Create the graph representing the cities, and the roads between them."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 39,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "G = nx.Graph()\n",
+    "for road in roads:\n",
+    "    G.add_edge(*road, distance=distance(*road, cities))"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Visualize the cities and road networks."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 43,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "image/png": "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\nLrnkknCXJ/WM1lCI1GHGGGbNmsU333xDSkpKuMuREPnuu+946qmnuPDCC+nfvz87duxgzpw5fPXV\nV8yZM0dhQsJCgUKkjuvYsSN/+MMfeOqpp9i2bVu4y5FKstayfv16brvtNtq1a0dycjK9evXi7bff\nZtOmTSQmJvKLXwRypRKR0FKgEKkHHnjgAdq3b8+ECROorQux66tDhw4xd+5cunfvTu/evfnvf//L\nY489xq5du/j73/9O7969teBWagQFCpF64JRTTmHmzJmsWbOGF154IdzlyEnIzc1lwoQJtG3blqSk\nJM477zxeffVV8vPzuf/++znrrLPCXaLIcRQoROqJ66+/nhtvvJHJkydz6NChcJcjZThy5AjLli3j\nV7/6FRdffDEvvPACkyZNYseOHbz44ov079+fBg30a1tqJv1kitQjf/vb3/j+++957LHHwl2K+Ni5\ncydTpkyhffv2xMfH06BBA5YtW8bnn3/O448/zrnnnhvuEkUqpEAhUo+cf/75TJ06lWeeeYbc3Nxw\nl1OvHT16lFdeeYXf/va3REZGMmfOHOLi4sjNzeWtt94iLi6Oxo3Lu2uLSM2iQCFSz9x777106NCB\n8ePHa4FmGOzZs4e//OUvREVFcf311/Pll1+Snp7OV199xcyZM4mOjg53iSKVogtbidQzTZo0Yfbs\n2fTt25fMzEyGDRsW7pLqPGstb7/9Nm63mxdeeAFjDEOHDmXZsmVcdtllOktD6gSNUIjUQ7Gxsdx8\n883cc8897N+/P9zl1FkHDhwgNTWVrl278n//93+89957/PnPf+bLL79k4cKFXH755QoTUmcoUIjU\nU9OnT+fgwYM8/PDD4S6lzvnoo49ISkrinHPOYeLEiURFRbF69Wq2bt3KPffcw5lnnhnuEkVCToFC\npJ5q164dDz/8MLNmzeLDDz8Mdzm1XlFREUuWLOGqq67il7/8JS+++CJ33303O3fu5J///CexsbE6\n5VPqNP10i9Rjd911FxdddBHjx4+nuLg43OXUStu3b+eBBx6gXbt23HLLLTRp0oQXXniBnTt38uij\nj9KuXbtwlyhSLRQoROqxRo0aMWfOHN5++20WL14c7nJqjaNHj/LSSy8xYMAAoqKimDt3Lrfccguf\nfPIJb7zxBoMGDaJRo0bhLlOkWilQiNRzV199NcOGDeP+++9n37594S6nRiu5a2uHDh244YYb+O67\n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\nAABJRU5ErkJggg==\n",
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7f579b17ad68>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "nx.draw_networkx(G, pos=cities, with_labels=True)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Compute the shortest path between city `D`, and all others."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 44,
+   "metadata": {
+    "collapsed": false,
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{'A': ['D', 'A'],\n",
+       " 'B': ['D', 'C', 'B'],\n",
+       " 'C': ['D', 'C'],\n",
+       " 'D': ['D'],\n",
+       " 'E': ['D', 'C', 'E']}"
+      ]
+     },
+     "execution_count": 44,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "nx.algorithms.shortest_path(G, source='D', weight='distance')"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Compute the shortest path distances between city `D`, and all others."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 47,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "B: 0.412\n",
+      "E: 0.535\n",
+      "C: 0.115\n",
+      "A: 0.510\n",
+      "D: 0.000\n"
+     ]
+    }
+   ],
+   "source": [
+    "for city, dist in nx.algorithms.shortest_path_length(G, source='D', weight='distance').items():\n",
+    "    print('{0}: {1:.3f}'.format(city, dist))"
+   ]
+  }
+ ],
+ "metadata": {
+  "anaconda-cloud": {},
+  "kernelspec": {
+   "display_name": "Python [conda env:py35]",
+   "language": "python",
+   "name": "conda-env-py35-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.5.2"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 1
+}
diff --git a/source-code/networkx/topo_sort.ipynb b/source-code/networkx/topo_sort.ipynb
new file mode 100644
index 0000000..3ba8d53
--- /dev/null
+++ b/source-code/networkx/topo_sort.ipynb
@@ -0,0 +1,183 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "# Topological sort"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Load the required libraries, and set matplotlib output."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "import networkx as nx\n",
+    "from topo_sort import show_sorted, create_graph, create_refs\n",
+    "import matplotlib.pyplot as plt\n",
+    "%matplotlib  inline"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "Show the references."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "[E02] Eve \"Hacking blowfish\", Hacker magazine, 2002\n",
+      "[C03] Carol \"Pufferfish: a new encryption algorithm\", Notices of the Luxemburg Academy of Sciences, 2003\n",
+      "[T04] Trent \"Review of modern encryption systems\", ACM Research on Security, 2004\n",
+      "[B02b] Bob \"Applying blowfish for email encryption\", Security research, 2002\n",
+      "[A03] Alice \"Proving blowfish to be mathemattically secure\", Security research, 2003\n",
+      "[B02a] Bob \"Applying blowfish for fun and profit\", Security research, 2002\n",
+      "[A01] Alice \"Encryption with blowfish\", Security research, 2001\n"
+     ]
+    }
+   ],
+   "source": [
+    "print('\\n'.join(n.format() for n in create_refs().values()))"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "Create the directed graph representing citations of publications."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "G = create_graph()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Show the resulting graph."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {
+    "collapsed": false,
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "data": {
+      "image/png": "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\nXFzMhaNGMSWRYHtI29wGfD+R4MJRo5RYiIi0I0ouJGNmzZnDlkSC74SwLYe/S+cHiQSz5sxprrqI\niGSQkgvJmKKiIu66+27K8NOpt5YL1i8DZtxzD0VFRaHEJyIi4Yh0tIhIuvHjx7N582amTp3K2/gx\nxgUtWH8b/oxFGX50yHXXXRdFmCIi0gY6cyEZd+uttzJ37lwqcnM5I5GgHPaNImnKbnznzf6JBBW5\nuZSVlTFlypTogxURkRZTciGxGD9+PK9XVVE8bBhXA70SCSYB9wMv4m+M9WLwehLwj4kEVwPFw4bx\nelWVzliIiLRjuiwisSkqKuLxxYupqqpi9uzZPPX448yuriZ1eLSZcfopp3BFMsnEiRM1KkRE5Aig\n5EJiV1xczMyZfrqZ2tpa3nrrLXbv3k3nzp3p06cP+fn5MUcoIiItoeRC2pX8/HxKSkriDkNERNpA\nfS5EREQkVEouREREJFRKLkRERCRUSi5EREQkVEouREREJFRKLkRERCRUSi5EREQkVEouREREJFRK\nLkRERCRUSi5EREQkVEouREREJFRKLkRERCRUSi5EREQkVEouREREJFRKLkRERCRUSi5EREQkVEou\nREREJFRKLkRERCRUSi5EREQkVEouREREJFRKLkRERCRUSi5EREQkVEouREREJFRKLkRERCRUSi5E\nREQkVEouREREJFRKLkRERCRUSi5EREQkVEouREREJFRKLkRERCRUSi6yTEVFRdwhtAtqh/3UFp7a\nwVM77Ke2iE5kyYWZdTOz+Wa21cw+MrMyMzv2EPUTZnaHmb1mZrVm9o6ZzTOznlHFmI30YfHUDvup\nLTy1g6d22E9tEZ0oz1yUA32BEcCXgPOAOYeonweUAP8ODAQuAU4DHo4wRhEREQlZIoqNmtnpwAXA\nYOfcy0HZDcBjZvZd59ym9HWcc9uCdVK38y3gRTM70Tm3IYpYRUREJFxRnbk4F/ioIbEIPAU44OwW\nbKcwWOfvIcYmIiIiEYrkzAXQA3gvtcA594mZfRgsa5aZdQZ+BpQ752oPUTUXYOXKla0MNbts3bqV\n5cuXxx1G7NQO+6ktPLWDp3bYT21xwHdnbpjbNefc4Vc2ux343iGqOHw/i0uBa5xzfdPW3wz80Dl3\nqL4XmFkC+B+gJzDsUMmFmV0FzD+8PRAREZFGXO2cKw9rYy09c/EL4NfN1FkLbAI+nVpoZkcBnwqW\n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\nQkREREL1v7KwaEZOUOU0AAAAAElFTkSuQmCC\n",
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7f8e30a8ed30>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "nx.draw_networkx(G, with_labels=True)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "Compute the topological sort, and print references."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "[A01] Alice \"Encryption with blowfish\", Security research, 2001\n",
+      "[B02a] Bob \"Applying blowfish for fun and profit\", Security research, 2002\n",
+      "[B02b] Bob \"Applying blowfish for email encryption\", Security research, 2002\n",
+      "[E02] Eve \"Hacking blowfish\", Hacker magazine, 2002\n",
+      "[T04] Trent \"Review of modern encryption systems\", ACM Research on Security, 2004\n",
+      "[C03] Carol \"Pufferfish: a new encryption algorithm\", Notices of the Luxemburg Academy of Sciences, 2003\n",
+      "[A03] Alice \"Proving blowfish to be mathemattically secure\", Security research, 2003\n"
+     ]
+    }
+   ],
+   "source": [
+    "show_sorted(G)"
+   ]
+  }
+ ],
+ "metadata": {
+  "anaconda-cloud": {},
+  "celltoolbar": "Slideshow",
+  "kernelspec": {
+   "display_name": "Python [conda env:py35]",
+   "language": "python",
+   "name": "conda-env-py35-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.5.2"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 1
+}
diff --git a/source-code/networkx/topo_sort.py b/source-code/networkx/topo_sort.py
new file mode 100755
index 0000000..02ce29c
--- /dev/null
+++ b/source-code/networkx/topo_sort.py
@@ -0,0 +1,116 @@
+#!/usr/bin/env python
+
+from argparse import ArgumentParser
+import networkx as nx
+
+
+class Reference(object):
+
+    def __init__(self, author, title, journal, year):
+        self._author = author
+        self._title = title
+        self._journal = journal
+        self._year = year
+        self._key = None
+
+    @property
+    def author(self):
+        return self._author
+
+    @property
+    def title(self):
+        return self._title
+
+    @property
+    def journal(self):
+        return self._journal
+
+    @property
+    def year(self):
+        return self._year
+
+    @property
+    def key(self):
+        return self._key
+
+    @key.setter
+    def key(self, ref_key):
+        self._key = ref_key
+
+    def format(self):
+        fmt_str = '[{key}] {author} "{title}", {journal}, {year}'
+        return fmt_str.format(key=self.key, author=self.author,
+                              title=self.title, journal=self.journal,
+                              year=self.year)
+    def __str__(self):
+        return self.key
+
+
+def create_refs():
+    refs = {
+        'A01': Reference(
+                    author='Alice',
+                    title='Encryption with blowfish',
+                    journal='Security research',
+                    year=2001,),
+        'B02a': Reference(
+                    author='Bob',
+                    title='Applying blowfish for fun and profit',
+                    journal='Security research',
+                    year=2002,),
+        'B02b': Reference(
+                    author='Bob',
+                    title='Applying blowfish for email encryption',
+                    journal='Security research',
+                    year=2002,),
+        'C03': Reference(
+                    author='Carol',
+                    title='Pufferfish: a new encryption algorithm',
+                    journal='Notices of the Luxemburg Academy of Sciences',
+                    year=2003,),
+        'E02': Reference(
+                    author='Eve',
+                    title='Hacking blowfish',
+                    journal='Hacker magazine',
+                    year=2002,),
+        'T04': Reference(
+                    author='Trent',
+                    title='Review of modern encryption systems',
+                    journal='ACM Research on Security',
+                    year=2004,),
+        'A03': Reference(
+                    author='Alice',
+                    title='Proving blowfish to be mathemattically secure',
+                    journal='Security research',
+                    year=2003,),
+    }
+    for key in refs:
+        refs[key].key = key
+    return refs
+
+
+def create_graph():
+    refs = create_refs()
+    citations = nx.DiGraph()
+    citations.add_edge(refs['A01'], refs['B02a'])
+    citations.add_edge(refs['A01'], refs['B02b'])
+    citations.add_edge(refs['A01'], refs['E02'])
+    citations.add_edge(refs['A01'], refs['A03'])
+    citations.add_edge(refs['A01'], refs['T04'])
+    citations.add_edge(refs['B02a'], refs['B02b'])
+    citations.add_edge(refs['B02a'], refs['T04'])
+    citations.add_edge(refs['E02'], refs['T04'])
+    citations.add_node(refs['C03'])
+    return citations
+
+
+def show_sorted(G):
+    nodes = nx.algorithms.topological_sort(G)
+    print('\n'.join([n.format() for n in nodes]))
+
+if __name__ == '__main__':
+    arg_parser = ArgumentParser(description='illustration of topological '
+                                            'sort')
+    options = arg_parser.parse_args()
+    G = create_graph()
+    show_sorted(G)
diff --git a/source-code/networkx/weighted_tree.xml b/source-code/networkx/weighted_tree.xml
new file mode 100644
index 0000000..b96f624
--- /dev/null
+++ b/source-code/networkx/weighted_tree.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?><graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
+  <key attr.name="weight" attr.type="double" for="edge" id="d0" />
+  <graph edgedefault="directed">
+    <node id="1.1.1" />
+    <node id="1.1.2.2" />
+    <node id="1.1.2.1" />
+    <node id="1.1.2" />
+    <node id="1.1.3.2" />
+    <node id="1.1" />
+    <node id="1.1.3.1" />
+    <node id="1.1.3" />
+    <node id="1" />
+    <edge source="1.1.2" target="1.1.2.2">
+      <data key="d0">0.0575438931688</data>
+    </edge>
+    <edge source="1.1.2" target="1.1.2.1">
+      <data key="d0">0.105301986657</data>
+    </edge>
+    <edge source="1.1" target="1.1.1">
+      <data key="d0">0.560607411083</data>
+    </edge>
+    <edge source="1.1" target="1.1.3">
+      <data key="d0">0.741221587377</data>
+    </edge>
+    <edge source="1.1" target="1.1.2">
+      <data key="d0">0.991426195271</data>
+    </edge>
+    <edge source="1.1.3" target="1.1.3.2">
+      <data key="d0">0.00397873408726</data>
+    </edge>
+    <edge source="1.1.3" target="1.1.3.1">
+      <data key="d0">0.128230916642</data>
+    </edge>
+    <edge source="1" target="1.1">
+      <data key="d0">0.538121395348</data>
+    </edge>
+  </graph>
+</graphml>
+

From 90c8b4e0bdbdbd555da33bdffcb4ccb5d1a991e8 Mon Sep 17 00:00:00 2001
From: Geert Jan Bex <geertjan.bex@uhasselt.be>
Date: Mon, 20 Jan 2020 12:24:54 +0100
Subject: [PATCH 5/6] Improve formatting

---
 source-code/xarray/xarray_intro.ipynb | 128 +++++++++++++++++++-------
 1 file changed, 94 insertions(+), 34 deletions(-)

diff --git a/source-code/xarray/xarray_intro.ipynb b/source-code/xarray/xarray_intro.ipynb
index 44958ac..633cc30 100644
--- a/source-code/xarray/xarray_intro.ipynb
+++ b/source-code/xarray/xarray_intro.ipynb
@@ -71,30 +71,80 @@
    "outputs": [
     {
      "data": {
+      "text/html": [
+       "<pre>&lt;xarray.DataArray (x: 11, y: 11)&gt;\n",
+       "array([[25.4988448 , 23.39724357, 20.24712019, 22.38314038, 20.00306701,\n",
+       "        25.11999731, 25.45432341, 23.80026017, 20.54738093, 21.03097739,\n",
+       "        18.92687934],\n",
+       "       [22.00398794, 20.27192054, 17.63385599, 18.72612225, 20.8484745 ,\n",
+       "        19.46559613, 18.42510929, 23.39567238, 19.25841855, 21.58056126,\n",
+       "        21.07231794],\n",
+       "       [18.61106092, 20.61739919, 20.53950365, 21.3798843 , 23.10975021,\n",
+       "        20.98018569, 21.34124172, 19.11502555, 17.58268715, 22.60328183,\n",
+       "        21.47545328],\n",
+       "       [19.67391651, 24.60202868, 19.7119848 , 23.0457134 , 22.18027301,\n",
+       "        19.93193015, 19.13480027, 18.64597415, 17.14602559, 18.27688404,\n",
+       "        19.95926802],\n",
+       "       [21.61161322, 21.05803646, 26.47579387, 19.28301912, 20.73629081,\n",
+       "        17.81248346, 21.97240871, 24.87112386, 21.17473823, 22.45417057,\n",
+       "        22.5146855 ],\n",
+       "       [21.3706365 , 21.17411047, 20.71771189, 21.32629413, 25.27117325,\n",
+       "        20.96454022, 16.50840133, 20.06063499, 17.64608346, 18.76171914,\n",
+       "        17.94025172],\n",
+       "       [19.63364958, 23.44396645, 19.26329555, 21.42314903, 24.00175585,\n",
+       "        15.86963786, 18.1071366 , 16.18780383, 19.01908846, 20.82975735,\n",
+       "        22.93974614],\n",
+       "       [23.30177657, 19.98747409, 21.95324933, 22.0727039 , 24.35636834,\n",
+       "        20.23531303, 20.71016625, 23.02026373, 23.55531591, 18.54822844,\n",
+       "        21.53877195],\n",
+       "       [20.52278161, 23.84750023, 19.01413235, 21.7909608 , 20.23068922,\n",
+       "        23.2231657 , 19.86638471, 24.61156825, 18.67185945, 22.82834313,\n",
+       "        21.77832921],\n",
+       "       [18.82637942, 19.37653728, 18.5068343 , 24.01998162, 16.6866677 ,\n",
+       "        20.93781913, 18.81118506, 22.78353883, 20.94002675, 22.99034824,\n",
+       "        19.76267955],\n",
+       "       [22.73095447, 21.43357868, 20.0418187 , 18.06314775, 14.91345132,\n",
+       "        23.3997994 , 19.56048114, 16.63938592, 20.70636447, 23.96504051,\n",
+       "        22.42441984]])\n",
+       "Coordinates:\n",
+       "  * x        (x) float64 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0\n",
+       "  * y        (y) float64 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0</pre>"
+      ],
       "text/plain": [
        "<xarray.DataArray (x: 11, y: 11)>\n",
-       "array([[20.060227, 20.343288, 22.493436, 20.886055, 19.599252, 19.9795  ,\n",
-       "        19.463129, 25.567439, 21.672808, 17.00054 , 19.591958],\n",
-       "       [18.393412, 16.544274, 19.472503, 23.419062, 20.918769, 19.231152,\n",
-       "        19.582383, 21.38485 , 22.895528, 19.82586 , 23.447652],\n",
-       "       [21.458348, 21.843564, 22.611372, 18.006569, 20.575531, 21.166873,\n",
-       "        22.006631, 18.940422, 20.571206, 23.026252, 20.922982],\n",
-       "       [22.736496, 21.494013, 20.76477 , 24.218455, 22.423822, 20.844336,\n",
-       "        22.972383, 22.169935, 18.982916, 20.076558, 21.534189],\n",
-       "       [20.385641, 22.899617, 21.14046 , 19.492904, 22.013288, 20.519298,\n",
-       "        17.047163, 24.69833 , 20.749292, 17.556841, 23.444134],\n",
-       "       [22.188399, 21.542768, 21.069173, 20.804404, 19.985631, 21.650881,\n",
-       "        19.957621, 20.733553, 15.845453, 20.586171, 23.194928],\n",
-       "       [20.631938, 20.546089, 21.234935, 18.799045, 23.066751, 19.738352,\n",
-       "        20.043838, 21.464738, 22.404247, 21.243846, 21.816928],\n",
-       "       [21.383564, 23.706478, 23.973886, 19.403355, 22.604506, 16.450427,\n",
-       "        19.649931, 21.500265, 16.411651, 26.416987, 22.197047],\n",
-       "       [21.212505, 22.172344, 20.169168, 21.490327, 17.34986 , 19.617111,\n",
-       "        19.777066, 18.771164, 21.021582, 19.224937, 19.965937],\n",
-       "       [19.058219, 24.294649, 21.671964, 21.274954, 23.989597, 21.86506 ,\n",
-       "        20.249017, 21.804745, 19.50452 , 23.047136, 23.045451],\n",
-       "       [22.091376, 18.088312, 19.849349, 22.912824, 19.700604, 19.021563,\n",
-       "        17.447241, 26.386473, 18.399266, 24.399055, 19.037564]])\n",
+       "array([[25.4988448 , 23.39724357, 20.24712019, 22.38314038, 20.00306701,\n",
+       "        25.11999731, 25.45432341, 23.80026017, 20.54738093, 21.03097739,\n",
+       "        18.92687934],\n",
+       "       [22.00398794, 20.27192054, 17.63385599, 18.72612225, 20.8484745 ,\n",
+       "        19.46559613, 18.42510929, 23.39567238, 19.25841855, 21.58056126,\n",
+       "        21.07231794],\n",
+       "       [18.61106092, 20.61739919, 20.53950365, 21.3798843 , 23.10975021,\n",
+       "        20.98018569, 21.34124172, 19.11502555, 17.58268715, 22.60328183,\n",
+       "        21.47545328],\n",
+       "       [19.67391651, 24.60202868, 19.7119848 , 23.0457134 , 22.18027301,\n",
+       "        19.93193015, 19.13480027, 18.64597415, 17.14602559, 18.27688404,\n",
+       "        19.95926802],\n",
+       "       [21.61161322, 21.05803646, 26.47579387, 19.28301912, 20.73629081,\n",
+       "        17.81248346, 21.97240871, 24.87112386, 21.17473823, 22.45417057,\n",
+       "        22.5146855 ],\n",
+       "       [21.3706365 , 21.17411047, 20.71771189, 21.32629413, 25.27117325,\n",
+       "        20.96454022, 16.50840133, 20.06063499, 17.64608346, 18.76171914,\n",
+       "        17.94025172],\n",
+       "       [19.63364958, 23.44396645, 19.26329555, 21.42314903, 24.00175585,\n",
+       "        15.86963786, 18.1071366 , 16.18780383, 19.01908846, 20.82975735,\n",
+       "        22.93974614],\n",
+       "       [23.30177657, 19.98747409, 21.95324933, 22.0727039 , 24.35636834,\n",
+       "        20.23531303, 20.71016625, 23.02026373, 23.55531591, 18.54822844,\n",
+       "        21.53877195],\n",
+       "       [20.52278161, 23.84750023, 19.01413235, 21.7909608 , 20.23068922,\n",
+       "        23.2231657 , 19.86638471, 24.61156825, 18.67185945, 22.82834313,\n",
+       "        21.77832921],\n",
+       "       [18.82637942, 19.37653728, 18.5068343 , 24.01998162, 16.6866677 ,\n",
+       "        20.93781913, 18.81118506, 22.78353883, 20.94002675, 22.99034824,\n",
+       "        19.76267955],\n",
+       "       [22.73095447, 21.43357868, 20.0418187 , 18.06314775, 14.91345132,\n",
+       "        23.3997994 , 19.56048114, 16.63938592, 20.70636447, 23.96504051,\n",
+       "        22.42441984]])\n",
        "Coordinates:\n",
        "  * x        (x) float64 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0\n",
        "  * y        (y) float64 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0"
@@ -139,9 +189,16 @@
    "outputs": [
     {
      "data": {
+      "text/html": [
+       "<pre>&lt;xarray.DataArray ()&gt;\n",
+       "array(17.63385599)\n",
+       "Coordinates:\n",
+       "    x        float64 0.1\n",
+       "    y        float64 0.2</pre>"
+      ],
       "text/plain": [
        "<xarray.DataArray ()>\n",
-       "array(19.472503)\n",
+       "array(17.63385599)\n",
        "Coordinates:\n",
        "    x        float64 0.1\n",
        "    y        float64 0.2"
@@ -182,9 +239,16 @@
    "outputs": [
     {
      "data": {
+      "text/html": [
+       "<pre>&lt;xarray.DataArray ()&gt;\n",
+       "array(17.63385599)\n",
+       "Coordinates:\n",
+       "    x        float64 0.1\n",
+       "    y        float64 0.2</pre>"
+      ],
       "text/plain": [
        "<xarray.DataArray ()>\n",
-       "array(19.472503)\n",
+       "array(17.63385599)\n",
        "Coordinates:\n",
        "    x        float64 0.1\n",
        "    y        float64 0.2"
@@ -383,11 +447,6 @@
     "print(type(temperature.values), temperature.values.dtype, temperature.values.shape)"
    ]
   },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": []
-  },
   {
    "cell_type": "markdown",
    "metadata": {},
@@ -2009,7 +2068,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 62,
+   "execution_count": 6,
    "metadata": {},
    "outputs": [],
    "source": [
@@ -2029,11 +2088,12 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 63,
+   "execution_count": 7,
    "metadata": {},
    "outputs": [],
    "source": [
-    "data[:, :, 0] = np.random.normal(loc=0.0, scale=1.0, size=(data.coords['x'].shape[0], data.coords['y'].shape[0]))\n",
+    "data[:, :, 0] = np.random.normal(loc=0.0, scale=1.0,\n",
+    "                                 size=(data.coords['x'].shape[0], data.coords['y'].shape[0]))\n",
     "for t in range(1, data.coords['t'].shape[0]):\n",
     "    data[:, :, t] = data[:, :, t - 1] + np.random.normal(loc=0.0, scale=0.1, size=data[:, :, 0].shape)"
    ]
@@ -2261,12 +2321,12 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.7.3"
+   "version": "3.7.6"
   },
   "toc-autonumbering": false,
   "toc-showcode": false,
   "toc-showmarkdowntxt": false
  },
  "nbformat": 4,
- "nbformat_minor": 2
+ "nbformat_minor": 4
 }

From f00573baf4be0e5c6740ea3a8d3fb68162d9c88c Mon Sep 17 00:00:00 2001
From: Geert Jan Bex <geertjan.bex@uhasselt.be>
Date: Mon, 20 Jan 2020 12:26:42 +0100
Subject: [PATCH 6/6] Update conda environment

---
 environment.yml                                 | 1 +
 python_for_data_science_linux64_conda_specs.txt | 1 +
 2 files changed, 2 insertions(+)

diff --git a/environment.yml b/environment.yml
index e75444a..7340a8c 100644
--- a/environment.yml
+++ b/environment.yml
@@ -19,4 +19,5 @@ dependencies:
   - seaborn
   - shapely
   - sqlalchemy
+  - xarray
   - xlrd
diff --git a/python_for_data_science_linux64_conda_specs.txt b/python_for_data_science_linux64_conda_specs.txt
index b30354c..714db60 100644
--- a/python_for_data_science_linux64_conda_specs.txt
+++ b/python_for_data_science_linux64_conda_specs.txt
@@ -181,6 +181,7 @@ https://repo.anaconda.com/pkgs/main/linux-64/shapely-1.6.4-py37hc5e8c75_0.conda
 https://repo.anaconda.com/pkgs/main/linux-64/altair-3.2.0-py37_0.conda
 https://repo.anaconda.com/pkgs/main/linux-64/fiona-1.8.11-py37h41e4f33_0.conda
 https://repo.anaconda.com/pkgs/main/linux-64/patsy-0.5.1-py37_0.conda
+https://repo.anaconda.com/pkgs/main/noarch/xarray-0.14.1-py_1.conda
 https://conda.anaconda.org/conda-forge/noarch/folium-0.10.0-py_0.tar.bz2
 https://repo.anaconda.com/pkgs/main/noarch/geopandas-0.6.1-py_0.conda
 https://repo.anaconda.com/pkgs/main/linux-64/statsmodels-0.10.1-py37hdd07704_0.conda
