From 2af2b1ec4f971497119da6545b18dd8049e1db1f Mon Sep 17 00:00:00 2001
From: k204232 <heil@dkrz.de>
Date: Thu, 10 Oct 2024 10:11:38 +0200
Subject: [PATCH] AH minor edits to xarray_intro_part1.ipynb

---
 xarray_intro_part1.ipynb | 3803 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 3803 insertions(+)
 create mode 100644 xarray_intro_part1.ipynb

diff --git a/xarray_intro_part1.ipynb b/xarray_intro_part1.ipynb
new file mode 100644
index 0000000..7bea305
--- /dev/null
+++ b/xarray_intro_part1.ipynb
@@ -0,0 +1,3803 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "id": "08a8d53e-167a-480b-beac-15bc6b378f94",
+   "metadata": {},
+   "source": [
+    "***\n",
+    "<p align=\"right\">\n",
+    "      <img src=\"https://www.dkrz.de/@@site-logo/dkrz.svg\" width=\"12%\" align=\"right\" title=\"DKRZlogo\" hspace=\"20\">\n",
+    "      <img src=\"https://wr.informatik.uni-hamburg.de/_media/logo.png\" width=\"12%\" align=\"right\" title=\"UHHLogo\">\n",
+    "</p>\n",
+    "<div style=\"font-size: 20px\" align=\"center\"><b> Python Course for Geoscientists, 8-11 October 2024</b></div>\n",
+    "<div style=\"font-size: 15px\" align=\"center\">\n",
+    "    <b>see also <a href=\"https://gitlab.dkrz.de/pythoncourse/material\">https://gitlab.dkrz.de/pythoncourse/material</a></b>\n",
+    "</div>\n",
+    "\n",
+    "***"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "f1b99208-9410-49dc-9d65-ba9290f86878",
+   "metadata": {},
+   "source": [
+    "<p align=\"center\">\n",
+    "      <img src=\"https://docs.xarray.dev/en/stable/_static/Xarray_Logo_RGB_Final.svg\" width=\"35%\" align=\"right\" title=\"xarraylogo\" hspace=\"20\">\n",
+    "</p>"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "814a8d6e-d0f5-4562-acab-75a2c957266b",
+   "metadata": {},
+   "source": [
+    "# xarray introduction I\n",
+    "\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "77e159a0-19ec-4a69-a871-cee6379d7ae1",
+   "metadata": {},
+   "source": [
+    "<br>\n",
+    "\n",
+    "______________________________________________________________________\n",
+    "# A) What is xarray?\n",
+    "______________________________________________________________________"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "e81e31bd-f599-448f-93b8-8017e91133ae",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    },
+    "tags": []
+   },
+   "source": [
+    "\n",
+    "*xarray* is a Python package that simplifies the handling of *multi-dimensional datasets*. It offers a wide range of functions for data manipulation, visualization, and advanced analytics, building on the capabilities of *numpy, Pandas, and Matplotlib.*\n",
+    "\n",
+    "The underlying data model of xarray is based on the network Common Data Form ([netCDF](https://www.unidata.ucar.edu/software/netcdf/)). netCDF is a standard file format widely used in climate science.  \n",
+    "*xarray* enables *efficient and intuitive data analysis* of netCDF data, but it also supports other file formats like *GRIB, HDF5, and Zarr*.  \n",
+    "\n",
+    "*xarray* documentation: https://docs.xarray.dev/en/stable/index.html"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "775514a1-b245-46ea-bfc9-9c4037be7ee4",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    },
+    "tags": []
+   },
+   "source": [
+    "## A1) xarray's data structure\n",
+    "\n",
+    "\n",
+    "xarray provides two primary data structures for handling multi-dimensional data: **DataArray** and **Dataset**.  \n",
+    "_see also https://tutorial.xarray.dev/fundamentals/01_datastructures.html_"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "a905fc01-5d69-411f-9e76-4505363928e2",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    },
+    "tags": []
+   },
+   "source": [
+    "### A1.1) DataArray \n",
+    "The DataArray class enhances multi-dimensional arrays by attaching dimension names, coordinates, and attributes. Essentially, a DataArray is a numpy ndarray enriched with additional metadata. The metadata describes the data using elements such as coordinate labels, named dimensions, units, attributes, and variable names. \n",
+    "\n",
+    "<span style=\"font-size: 1.1em; color: blue; \">class xarray.DataArray(data=nan, dims=None, coords=None, attrs=None, name=None, ..., ...)</span>\n",
+    "\n",
+    "<div style=\"margin-left: 20px;\">\n",
+    "\n",
+    "**data**:  \n",
+    "Values of the data variable as numpy ndarray or ndarray-like.\n",
+    "\n",
+    "**dims**:  \n",
+    "Dimensions represent the axes along which the data is organized. In xarray, each dimension is assigned a unique name.  \n",
+    "_Note: Commonly, the dimension order in multidimensional Earth Science data is (time, level, latitude, longitude)_\n",
+    "\n",
+    "**coords**:  \n",
+    "Coordinates (\"tick labels\") provide descriptive labels for the dimensions of your data, offering additional context and meaning to the data points along each dimension.\n",
+    "\n",
+    "**attrs**:  \n",
+    "Attributes, also known as metadata, are additional pieces of information attached to DataArrays, coordinate variables and/or Datasets. They include descriptive information such as units, CF standard_name, FillValue attributes, and comments.\n",
+    "\n",
+    "**name**:  \n",
+    "Name of data variable.  \n",
+    "\n",
+    "</div>"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "a39d647e-dea2-4cd4-b426-2c4ba5ea1a39",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    },
+    "tags": []
+   },
+   "source": [
+    "![xr1_DataStructure.png](../images/xr1_DataStructure.png)  \n",
+    "*Figure 1: An overview of xarray’s main data structures (adapted from https://docs.xarray.dev/en/stable/_images/dataset-diagram.png)*"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "9edeac20-70a5-4066-be92-84f07007fab1",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    },
+    "tags": []
+   },
+   "source": [
+    "### A1.2) DataSet\n",
+    "\n",
+    "A Dataset class is a dictionary-like collection of one or more DataArray objects with aligned dimensions.  \n",
+    "It serves as a container for organizing and managing multiple data variables within a coherent structure, mirroring the structure of a netCDF data file object.\n",
+    "\n",
+    "<span style=\"font-size: 1.1em; color: blue; \">class xarray.Dataset(data_vars=None, coords=None, attrs=None)</span>\n",
+    "\n",
+    "<div style=\"margin-left: 20px;\">\n",
+    "\n",
+    "**data_vars**:  \n",
+    "A dictionary-like organization of different data variables within a dataset, allowing access to these variables by their respective names.  \n",
+    "Each dimension must have the same length in all data variables in which it appears.  \n",
+    "\n",
+    "**coords**:\n",
+    "Dataset coordinates represent the coordinates of all data variables in the dataset, whether shared or not. They serve as a unified reference framework, helping users understand how the data is structured.\n",
+    "\n",
+    "**attrs**:\n",
+    "Global attributes associated with this dataset, such as e.g. Conventions, creator, history, references.\n",
+    "\n",
+    "</div>\n",
+    "\n",
+    "__Note__: The dimensions (dims) are not passed directly as an argument when creating the dataset.  \n",
+    "Instead, they are inferred from the shape of the data variables and coordinates that you provide.\n",
+    "\n",
+    "\n",
+    "\n",
+    "<br>"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "6c3ec783-efd6-4f3e-bdac-b5744de290c9",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    },
+    "tags": []
+   },
+   "source": [
+    "_For more details on xarray’s main data structures, see also [Hoyer and Hamman (2017); DOI: 10.5334/jors.148](https://openresearchsoftware.metajnl.com/articles/10.5334/jors.148) Figure 2._"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "252d06c6-fa7c-46e3-8241-2c17d50d856d",
+   "metadata": {
+    "tags": []
+   },
+   "source": [
+    "<br>\n",
+    "\n",
+    "______________________________________________________________________\n",
+    "# B) Preparation: Configure the Notebook\n",
+    "______________________________________________________________________"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "77c14150-5cc1-42c2-b819-c0351ba9edfb",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "outputs": [],
+   "source": [
+    "import xarray as xr\n",
+    "import numpy as np\n",
+    "import pandas as pd \n",
+    "\n",
+    "\n",
+    "# Just in case: To install packages in your local directory on a system kernel in Levante or elsewere.\"\"\"\n",
+    "try:\n",
+    "    import cfgrib\n",
+    "except ImportError:\n",
+    "    import subprocess\n",
+    "    subprocess.run([\"bash\", \"-c\", \"pip install --user ecmwflibs --quiet\"])\n",
+    "\n",
+    "%matplotlib inline\n",
+    "\n",
+    "import matplotlib.pyplot as plt\n",
+    "import matplotlib as mpl\n",
+    "\n",
+    "\n",
+    "\n",
+    "# Set this to render all evaluated output of a cell\n",
+    "from IPython.core.interactiveshell import InteractiveShell\n",
+    "InteractiveShell.ast_node_interactivity = \"all\"\n",
+    "\n",
+    "\n",
+    "# Set default figure size and font size\n",
+    "mpl.rcParams.update({\n",
+    "    \"figure.figsize\": (3.5, 2.5),\n",
+    "    \"font.size\": 9\n",
+    "})"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "de21481f-f17b-4097-9259-496462a9ddfe",
+   "metadata": {},
+   "source": [
+    "__Note__: *xr* serves as an alias for the *imported xarray package*."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "b87bed17-e651-4791-850e-688c75afb20c",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "source": [
+    "<br>\n",
+    "\n",
+    "______________________________________________________________________\n",
+    "# C) xr.DataArray() Showcases and Exercises\n",
+    "______________________________________________________________________\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "7f87cdb2-6255-4e18-8299-08e004b96ded",
+   "metadata": {
+    "tags": []
+   },
+   "source": [
+    "The `xr.DataArray()` constructor call in xarray is used to create a multi-dimensional array-like object that encapsulates a numpy ndarray or another ndarray-like data structure (referred to as data).  \n",
+    "This constructor call accepts optional additional keyword arguments to provide **labeled dimensions (dims), coordinates (coords), a name (name), and metadata (attrs)**. Below is the general syntax:\n",
+    "\n",
+    "```python\n",
+    "xr.DataArray(data,\n",
+    "             coords=None,\n",
+    "             dims=None,\n",
+    "             name=None,\n",
+    "             attrs=None\n",
+    "            )\n",
+    "```\n",
+    "__Note__: *xr* serves as an alias for the *imported xarray package*.  \n",
+    "\n",
+    "The constructor call `xr.DataArray()` returns a data object with a default data structure, consisting of dimension names, coordinates, indexes, and attributes.  \n",
+    "*If not provided with the `xr.DataArray()` constructor call, these presettings are empty.* The dimensions have the default names dim_0, dim_1,.... You can, however, modify them afterwards. \n",
+    "\n",
+    "It\"s important to **configure coordinate values** properly not only for xarray but also for other software tools. **Labeled geospatial** information from coordinates is crucial for various tasks, including:\n",
+    "\n",
+    "* **Plotting**: Mapping data onto a real-world grid for visualization.\n",
+    "* **Analysis**: Performing routines such as calculating area-weighted means.\n",
+    "\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "6f8dc295-da8b-43e3-84ed-b47c228f86b4",
+   "metadata": {},
+   "source": [
+    "***\n",
+    "\n",
+    "### C1 Showcase: Construct a \"naked\" xarray DataArray and modify it"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "bfd34065-71cd-4a28-be7b-41fb9d26f14b",
+   "metadata": {},
+   "source": [
+    "To create a basic xarray DataArray, you can simply pass a numpy ndarray to the `xr.DataArray()` constructor call.  "
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "4942104e-047f-42b5-856b-935399067740",
+   "metadata": {},
+   "source": [
+    "#### C1.1: Construct DataArray"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "3744f16b-3b33-4fd2-a308-45ec4e121db4",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#== Creating a numpy ndarray with shape (2, 4)\n",
+    "nlat, nlon  = 2, 4\n",
+    "ndarray = np.random.rand(nlat, nlon) * 10   # or e.g. np.arange(1, nlat * nlon + 1).reshape(nlat,nlon) \n",
+    "ndarray"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "0754376b-82c2-4553-af59-f27a97e1147f",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#== Creating a plain xarray DataArray\n",
+    "da1 = xr.DataArray(ndarray)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "23bb9bb7-d59f-4b0d-aed5-a611868c883f",
+   "metadata": {},
+   "source": [
+    "#### C1.2: Look at the DataArray"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "27c279b9-b3e3-44da-9e7d-cd129379f2d2",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#== Look at da1 in plain text view\n",
+    "print(da1)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "7af1bfe3-c055-45dc-887e-c7f1be838614",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#== Look at da1 in HTML View\n",
+    "da1"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "fc7f81e5-bc97-4ef2-a128-71329022cf2e",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#== Displaying individual components of the DataArray\n",
+    "print(\"Data Array Components:\")\n",
+    "print(\"=======================\")\n",
+    "print(f\"Data:\\n{da1.data}\\n\")\n",
+    "print(f\"Dimensions: {da1.dims}\")\n",
+    "print(f\"Attributes: {da1.attrs}\")\n",
+    "print(f\"Name: {da1.name}\")\n",
+    "print(f\"Shape: {da1.shape}\")\n",
+    "print(f\"Size: {da1.size}\")\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "57870275-4ac6-4d50-8fe1-839232242194",
+   "metadata": {},
+   "source": [
+    "#### C1.3: Rename the DataArray dimensions with rename()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "ec1eba23-b48d-4d22-a6a8-fd15bedbde50",
+   "metadata": {},
+   "source": [
+    "The DataArray class comes with many built-in methods.  \n",
+    "To see all possible methods available for a DataArray object, you can e.g. use the `dir()` function:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "5f5363f3-3f85-4a68-83d6-4d275aba3a38",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#dir(da1)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "bd7afd55-a11c-464a-ac9e-ca5789509628",
+   "metadata": {},
+   "source": [
+    "One such method is `rename`, which allows you to change the names of dimensions and coordinates of the DataArray.\n",
+    "\n",
+    "You can view the details of the `rename` method using e.g. `help(da1.rename)` or https://docs.xarray.dev/en/stable/generated/xarray.DataArray.rename.html. "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "3f6add14-a39f-41ea-b923-e27b446ef654",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "help(da1.rename)   #--alternative: da1.rename?"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "2ef0defa-3e21-4292-bbc6-44d3700cd7f4",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#== Renaming dimension names of the DataArray with .rename()\n",
+    "\n",
+    "# Note: the rename method creates a new DataArray object, it does not modify da1 in-place.\n",
+    "da2 = da1.rename({\"dim_0\": \"lat\", \"dim_1\": \"lon\"})\n",
+    "print(da2)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "2d4cd4aa-3e4b-4c40-81be-12e766dc0bae",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "print(da2.coords) "
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "9ed54b56-85f6-41a0-b097-07f64c41197a",
+   "metadata": {},
+   "source": [
+    "#### C1.4: Assign coordinate variables to the DataArray with assign_coords()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "06c9b6d7-4902-454e-aaf6-ea8c0bd3f260",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#== Creating coordinate variables lons and lats\n",
+    "lons, lats  = np.linspace(0., 20., nlon), np.linspace(-3., 3., nlat)\n",
+    "\n",
+    "# Note: the assign_coords method creates a new DataArray object, it does not modify da2 in-place.\n",
+    "da3 = da2.assign_coords({\"lon\": lons, \"lat\": lats})\n",
+    "print(da3)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "cf95e961-7047-4f65-a555-27ff3fdd4b70",
+   "metadata": {},
+   "source": [
+    "#### C1.5: Assign a name to the DataArray"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "a59dbc4b-b3d5-4c75-9425-6baf867ad93b",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "da3.name = \"var1\"\n",
+    "print(da3)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "e8e26eaf-2611-4fb6-bf17-308627b67b7e",
+   "metadata": {},
+   "source": [
+    "#### C1.6: Assign attributes to the data variable with attrs"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "30ccdbba-5860-42e0-b9af-77da0f5d26ee",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "#   Tip: myda.attrs[\"attribute_key\"] = \"attribute_value\" #- attaches metadata attributes to the data array\n",
+    "da3.attrs[\"standard_name\"] = \"age_of_sea_ice\"    #- CF standard name for variable\n",
+    "da3.attrs[\"units\"] = \"mm\"                        #- units associated to CF standard name"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "a6d2c3eb-7565-42fc-b399-59bf772c758f",
+   "metadata": {},
+   "source": [
+    "_**Note**_: For CF standard names, see https://cfconventions.org/Data/cf-standard-names/current/build/cf-standard-name-table.html\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "e191937e-9571-49c9-8ed3-9dc85357b61f",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "print(da3)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "ce80854a-cb0c-43dc-bd14-282a3af840c2",
+   "metadata": {},
+   "source": [
+    "#### C1.7: Assign attributes to the coordinate variable lon with attrs"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "e1836b8e-3827-4cc8-967e-60a77c02c439",
+   "metadata": {
+    "tags": []
+   },
+   "source": [
+    "_**Note**_: There are two options to access a coordinate variable:\n",
+    "  *         da3.MYVAR:    attribute-style access\n",
+    "  *         da3[\"MYVAR\"]: dictionary-style"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "286d9f25-9854-41ad-af9d-4c4f9b3dc967",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "da3.lon.attrs[\"standard_name\"] = \"longitude\"  #- same as da3[\"lon\"].attrs[\"standard_name\"] = \"longitude\"\n",
+    "da3[\"lon\"].attrs[\"units\"]      = \"degrees_east\""
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "f7368d01-ec89-4e49-adfc-794798ba3487",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "da3"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "b0fd80cc-237f-48cb-82f3-12d88228b53f",
+   "metadata": {},
+   "source": [
+    "#### C1.8: Access and inspect individual components of the DataArray"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "54cfef0e-4da2-4589-bda8-d231cb00e100",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "mycoord = \"lon\"\n",
+    "\n",
+    "# Access the \"units\" attribute of the coordinate `mycoord` \n",
+    "da3[mycoord].attrs[\"units\"]\n",
+    "\n",
+    "# Check the type of the object corresponding to `mycoord`\n",
+    "type(da3[mycoord])\n",
+    "\n",
+    "# Retrieve the raw numpy array of values associated with the coordinate `mycoord`\n",
+    "da3[mycoord].values\n",
+    "\n",
+    "# Retrieve the data type (dtype) of the values in the `mycoord` coordinate \n",
+    "da3[mycoord].values.dtype"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "498f25f5-7d7d-4250-9731-114c711f0113",
+   "metadata": {},
+   "source": [
+    "***\n",
+    "\n",
+    "### C2 Exercise xr.DataArray()\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "ed37edda-48b4-4447-954f-e0779b19dd11",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# 1. Generate a 3-dimensional xarray DataArray and look at it in plain text view.\n",
+    "\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "3cc0a54c-4e88-4a2e-adf6-b2daea344bcd",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# 2. Change the default dimension names and add coordinate values. \n",
+    "#   Tip: use myDataArray.assign_coords(t=tcoords, y=ycoords, x=xcoords)\n",
+    "\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "6b22d453-a20b-4ad4-980a-ee4067236cf6",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# 3. Print the coordinates and the dimensions. \n",
+    "#    Tip: These are referred to as `coords` and `dims`. \n",
+    "#    Inspect the type of these objects using the `type()` function and the dtype() attribute.\n",
+    "#    Also, check the type of the data object stored in the DataArray. \n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "8af37379-0a87-450b-b811-9633fc4fdcae",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# 4. Add some attributes, including a standard_name and units attribute.\n",
+    "#   Tip: myDataArray.attrs[\"attribute_key\"] = \"attribute_value\"\n",
+    "#   For CF standard names, see https://cfconventions.org/Data/cf-standard-names/current/build/cf-standard-name-table.html\n",
+    "\n",
+    "\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "5ab568b7-edc6-47d5-815b-c706a18a7c72",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# 5. Look at the new DataArray in html-view\n",
+    "#    Tip: try also out myDataArray.head(2) the first two elements from your DataArray.\n",
+    "     "
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "11c1a116-afaa-4aaa-8206-b9d3e65041bd",
+   "metadata": {
+    "tags": []
+   },
+   "source": [
+    "<br>\n",
+    "\n",
+    "#### C2 Solution Exercise xr.DataArray()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "6783227d-9eda-4d61-98ab-a429873fe48a",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# 1. Generate a 3-dimensional xarray DataArray and print in in plain text view.\n",
+    "ntime, nlat, nlon = 3, 5, 2\n",
+    "mydata            = np.random.random((ntime, nlat, nlon))\n",
+    "myda1              = xr.DataArray(mydata)\n",
+    "print(myda1)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "2c832062-2276-4de6-9965-a34024315de2",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# 2. Change the default dimension names and add coordinate values. \n",
+    "myda2          = myda1.rename({\"dim_0\":\"time\", \"dim_1\":\"lat\", \"dim_2\":\"lon\"})\n",
+    "tcoords        = [\"2022-03-01\", \"2022-03-02\", \"2022-03-03\"]\n",
+    "# better alternatives:\n",
+    "#tcoords        = xr.cftime_range(start=\"2022-03-01\", periods=ntime, freq=\"D\") \n",
+    "#tcoords        = pd.date_range(\"2022-03-01\", periods=ntime, freq=\"D\")         #-- with pandas\n",
+    "ycoords        = [30, 31, 32, 33, \"b\"]\n",
+    "xcoords        = np.linspace(1, 4, nlon)\n",
+    "myda3          = myda2.assign_coords(time=tcoords, lat=ycoords, lon=xcoords)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "4499e621-f38d-4d4f-b421-ccb4e7678846",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# 3. Print the coordinates and the dimensions and their types.\n",
+    "\n",
+    "myda3.coords\n",
+    "myda3.dims\n",
+    "\n",
+    "print(f\"object type of coords = {type(myda3.coords)}\")\n",
+    "print(f\"dtype of latitude coordinate = {myda3['lat'].values.dtype}\")\n",
+    "print(f\"object type of dims = {type(myda3.dims)}\")   \n",
+    "\n",
+    "#  print the type of the data object and is data type\n",
+    "print(f\"object type of data = {type(myda3.data)}\")\n",
+    "print(f\"data type of data = {myda3.lat.dtype}\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "10c8e399-6de1-40c9-a8b0-b72237e477ee",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# 4. Add some attributes, including a standard_name attribute and a units.\n",
+    "#   Tip: myDataArray.attrs[\"attribute_key\"] = \"attribute_value\"\n",
+    "#   For CF standard names, see https://cfconventions.org/Data/cf-standard-names/current/build/cf-standard-name-table.html\n",
+    "\n",
+    "myda3.attrs[\"standard_name\"] = \"fire_temperature\"\n",
+    "myda3.attrs[\"units\"] = \"K\"\n",
+    "myda3.attrs[\"comment\"] = \"dummy data\"\n",
+    "\n",
+    "myda3.lat.attrs[\"standard_name\"] = \"latitude\"\n",
+    "myda3.lat.attrs[\"units\"] = \"degrees_north\"\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "b6262cdb-55ea-46f8-bb38-aa7edfb21992",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# 5. Look at the new DataArray in html-view\n",
+    "#    Tip: try also out myDataArray.head(2) to subset the first two elements of your DataArray.\n",
+    "\n",
+    "myda3\n",
+    "\n",
+    "myda3.head(2)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "28343707-be55-4b67-9a46-66498a700a46",
+   "metadata": {},
+   "source": [
+    "***\n",
+    "\n",
+    "### C3 Showcase: Create a DataArray with metadata with a single DataArray() call"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "aab547d7-698f-4dc5-9622-cee17c94a1a3",
+   "metadata": {},
+   "source": [
+    "When creating a DataArray with xr.DataArray(), you can directly include:\n",
+    "\n",
+    "* name:   Assign a name to the DataArray.\n",
+    "* dims:   Specify dimension names (as tuple)\n",
+    "* coords: Define dimension values for alignment and indexing  \n",
+    "          (as dictionary with key=>dimension name; value=> array/list representing coordinate values)\n",
+    "* attrs:   Attach metadata attributes to the DataArray (as dictionary)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "8a1da962-beb0-4ac3-97cf-fdac4568bd9c",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "da4 = xr.DataArray(data=ndarray, \n",
+    "                   name=\"var1\",\n",
+    "                   dims=(\"lat\",\"lon\"), \n",
+    "                   coords={\"lat\": lats, \n",
+    "                           \"lon\": lons},\n",
+    "                   attrs={\"standard_name\":\"age_of_sea_ice\",\n",
+    "                          \"units\": \"mm\"})"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "38911a76-501f-487a-b9e9-55b17a603414",
+   "metadata": {},
+   "source": [
+    "Note: The xr.DataArray() function does not allow for direct specification of coordinate metadata within the `coords`\u001b parameter.  \n",
+    "These metadata attributes for coordinates have to be added afterwards."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "95786b3a-9039-455d-9504-0341ca7da3b1",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "da4[\"lon\"].attrs={\"standard_name\":\"longitude\", \"units\":\"degrees_east\"}\n",
+    "da4[\"lat\"].attrs={\"standard_name\":\"latitude\", \"units\":\"degrees_north\"}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "2cbd0c1d-f75c-4838-b451-03d9415c8477",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "da4"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "176dc1b3-ba4b-4472-95ee-843a6e138c39",
+   "metadata": {},
+   "source": [
+    "***"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "4e2555e5-62a7-470c-a0ea-22154af2a8fa",
+   "metadata": {},
+   "source": [
+    "### C4 Exercise xr.DataArray()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "676a6b1a-bf7c-4d00-b692-2b611177140e",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# 1. Create the same DataArray as in C2 with just one call of xr.DataArray  \n",
+    "#     except for the attachment of coordinate variable attributes\n",
+    "\n",
+    "#    TIP:\n",
+    "#   da = xr.DataArray(\n",
+    "#       data=ndarray,                # The data array (e.g., numpy array)\n",
+    "#           dims=(tuple...),             # Tuple of dimension names\n",
+    "#           coords={dictionary...},      # Dictionary of coordinates\n",
+    "#           attrs={dictionary...}        # Dictionary of attributes for the data array\n",
+    "#       )\n",
+    "\n",
+    "\n",
+    "\n",
+    "\n",
+    "\n",
+    "\n",
+    "\n",
+    "# 2. Try using a different dimension order when creating the DataArray. \n",
+    "#    Does this work? what if no coordinates are specified?\n",
+    "\n",
+    "\n",
+    "\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "5db43695-50eb-4175-8a83-2666fd4de808",
+   "metadata": {},
+   "source": [
+    "<br>\n",
+    "\n",
+    "#### C4 Solution Exercise xr.DataArray()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "2b3a0fde-d734-465b-b16e-61e2018b6327",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "# 1. Create the same DataArray as in C2 with just one call of xr.DataArray, \n",
+    "\n",
+    "myda4 = xr.DataArray(mydata, \n",
+    "                    dims=(\"time\", \"lat\", \"lon\"), \n",
+    "                      coords={\"time\": tcoords, \n",
+    "                             \"lat\":   ycoords,\n",
+    "                             \"lon\":   xcoords},\n",
+    "                      attrs=myda3.attrs)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "d497ee63-0818-4322-96e0-c5aa0333f4a2",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "# 2. Try using a different dimension order when creating the DataArray, does this work?\n",
+    "#    To try it out, comment out the codeblock\n",
+    "code_block = '''\n",
+    "myda5 = xr.DataArray(mydata, dims=(\"time\", \"lon\", \"lat\"), \n",
+    "                      attrs=myda3.attrs,\n",
+    "                      coords={\"time\": tcoords,\n",
+    "                              \"lat\":   ycoords,\n",
+    "                              \"lon\":   xcoords},)\n",
+    "'''\n",
+    "# Answer: raises an error because when coordinates are provided, \n",
+    "#         Xarray checks that the shape of the data matches the size of the coordinates, \n",
+    "#         and in this case, there is a mismatch\n",
+    "#         If no coordinates are provided, dims just provides the names for the dimensions with no shape check.\n",
+    "\n",
+    "myda5 = xr.DataArray(mydata, dims=(\"time\", \"lon\", \"lat\"), \n",
+    "                      attrs=myda3.attrs)\n",
+    "myda5"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "f60b6143-b4dd-4abb-addc-d963986dfe1f",
+   "metadata": {
+    "tags": []
+   },
+   "source": [
+    "***"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "cf9c606d-7fc9-4405-930d-2f41477371ab",
+   "metadata": {
+    "tags": []
+   },
+   "source": [
+    "### C5 Showcase: Plotting functionality on DataArrays "
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "6b0cb7af-b1d8-4fd2-84ff-3372ccbd4da6",
+   "metadata": {
+    "tags": []
+   },
+   "source": [
+    "xarray DataArray objects can be plotted by invoking the `plot()` method. <br> \n",
+    "\n",
+    "Principally, it is possible to customize the plot by providing arguments. <br>\n",
+    "However, compared to more advanced plotting libraries like Matplotlib, there is only *a limited set of customization options*."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "c0731464-5fc3-4a85-a159-231372c43e5a",
+   "metadata": {
+    "tags": []
+   },
+   "source": [
+    "When plotting xarray DataArray objects using the `plot()` method, the default chart type is automatically determined based on the dimensionality of the data. <br>\n",
+    "You can also explicitly specify a chart type by using `plot.CHARTTYPE()`, with CHARTTYPE being line, hist, pcolormesh, scatter, etc...<br> \n",
+    "The default chart types are: \n",
+    "- 1-D data:  Line2D plot &emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;    ==> equivalent to plot.line()\n",
+    "- 2-D data: QuadMesh plot (resembling a filled contour plot) &emsp;&emsp; ==> equivalent to plot.pcolormesh()\n",
+    "- other dimenionality: histogram plot  &emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp; ==> equivalent to plot.hist()  \n",
+    "see https://docs.xarray.dev/en/stable/generated/xarray.DataArray.plot.html\n",
+    "\n",
+    "_**NOTE**_: By default, the  `plot()` method call uses metadata provided by the DataArray for plotting the labels.\n",
+    "\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "00f79a62-435a-4999-b038-cf9d863d4cac",
+   "metadata": {},
+   "source": [
+    "#### C5.1: Make a default chart type plot"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "84519740-713f-4810-a29f-c63fadaee760",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "#-- Check the dimensionality of the DataArray da4\n",
+    "da4.dims"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "9ca36b6c-2b96-4bba-9ab6-5f6bae5778bc",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "#-- Create a default plot from DataArray da4 with plot()\n",
+    "da4.plot()   #-- equivalent to da4.plot.pcolormesh() as da4 is 2-dim"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "64e58618-0db2-4e78-9b94-96d5768d1d1c",
+   "metadata": {},
+   "source": [
+    "#### C5.2: Make a histogram plot"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "6e3597a6-6a5c-45e3-b355-51a97aa26e79",
+   "metadata": {},
+   "source": [
+    "The da.plot.hist() method returns a tuple of size 3, with\n",
+    "\n",
+    "\t1.\tValues: counts for each bin\n",
+    "\t2.\tEdges: bin edges\n",
+    "\t3.\tAxes:  Matplotlib axes object of the plot\n",
+    "    \n",
+    "This allows you extracting the computed values of the histogram from the xarray plot.hist() method."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "831f6e51-593d-4f66-918a-5cbf16bc24cb",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#-- Create a histogram plot from DataArray da4\n",
+    "da4.plot.hist()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "293493da-b0e6-45c6-8d82-6d83221a3acc",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#-- Create a histogram plot from DataArray da4, specify the bin edges and extract computed values\n",
+    "hist_values, hist_edges, ax = da4.plot.hist(bins=[0, 2, 4, 6])   \n",
+    "print(hist_values)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "346988a6-3260-4301-82b2-7f89e65d6632",
+   "metadata": {},
+   "source": [
+    "#### C5.3: Make a scatter plot"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "04095e5a-8fa3-45a1-ad2b-2f0872da7fc2",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#-- Note: plot.scatter() method on DataArray has many limitations. \n",
+    "#-- E.g. it always plots the variable’s values on the y-axis\n",
+    "#-- You can, however, specify which dimension is plotted on the x-axis by passing the dimension name as an argument.\n",
+    "\n",
+    "da4.plot.scatter()        #-- same as da4.plot.scatter(x=\"lat\") or da4.plot.scatter(y=\"lat\")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "0f46accb-9758-41a9-8a84-bcc12cfca39f",
+   "metadata": {},
+   "source": [
+    "#### C5.4: Make a pcolormesh plot and customize it"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "d4364096-076b-47d9-87d4-a76391503cce",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "#da4.plot.pcolormesh?"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "2f6c3e6d-9cf6-4a10-9efb-0eec0f9daee5",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "da4.plot.pcolormesh(figsize=(3, 2), cmap=\"Reds\", add_colorbar=True,\n",
+    "                               cbar_kwargs={\"label\": \"This is the colorbar label\",\n",
+    "                                            \"shrink\": 1.1})\n",
+    "#== Additional customizations using Matplotlib functions \n",
+    "#== since these are not accessible with the plot() function.\n",
+    "plt.title(\"mytitle\");\n",
+    "plt.ylabel(\"latitude\");\n",
+    "plt.grid(\"on\");"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "1e64dde4-1cd9-4dee-b136-401e1e884e9c",
+   "metadata": {
+    "tags": []
+   },
+   "source": [
+    "_**NOTE**_: Alternatively, you could e.g. also do plot.contour() or plot.contourf().  \n",
+    "For available plotting methods, `dir(da4.plot)`"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "d606ad5b-5221-4283-adc1-48f2eda317fd",
+   "metadata": {},
+   "source": [
+    "#### C5.5: Make a line plot"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "ffb9a6be-560f-409f-bdd2-6e3db3bf2f7b",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "#== Create a 1D DataArray by slicing da4 and plot a line plot\n",
+    "da4.lat.values"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "941cc526-bc72-4f3c-8f7f-1052ff265b38",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "da4[0,:].plot(figsize=(3, 2), color=\"purple\", marker=\"o\"); "
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "a0ba3fef-1a8f-4dab-8d49-f64d9cef9920",
+   "metadata": {},
+   "source": [
+    "<br>\n",
+    "\n",
+    "______________________________________________________________________\n",
+    "# D) xr.DataDataset() Showcases and Exercises\n",
+    "______________________________________________________________________\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "4ad1ddf4-041a-499f-a41d-68ee88ff147e",
+   "metadata": {},
+   "source": [
+    "***\n",
+    "\n",
+    "### D1 Showcase: Convert an xarray.DataArray to an xarray.Dataset and modify metadata\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "c23d0e17-3729-4c3d-ba82-dfddcf33c82d",
+   "metadata": {},
+   "source": [
+    "#### D1.1: Create the Dataset with `.to_dataset()`"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "d0ec789f-0ee7-4cb1-b668-167616e7a899",
+   "metadata": {},
+   "source": [
+    "You can transform an xarray DataArrays into a xarray Dataset by using the DataArray.to_dataset() function call."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "8fadc3c7-8907-491d-92d8-aa38c6925e40",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#== We use the xarray DataArray da4 from from the C3 Showcase\n",
+    "ds1 = da4.to_dataset()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "25311196-60b3-40c0-87f1-7482e39d61c0",
+   "metadata": {},
+   "source": [
+    "_**NOTE**_: converting an unnamed DataArray to a Dataset will raise a ValueError  \n",
+    "            unless an explicit name is provided an argument to the to_dataset() call  \n",
+    "            ds = da_unnamed.to_dataset(name=\"dsvarname\")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "4468f775-f55a-4930-bb1a-ab85d0a7a2e3",
+   "metadata": {},
+   "source": [
+    "#### D1.2: Look at the Dataset"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "d665a100-55b9-4abe-885a-a5a0f0a1bc5f",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#== Print the xarray Dataset.\n",
+    "print(ds1)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "b890f123-473b-46b0-b396-93bb8133c219",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#== Print the input DataArray da4 for comparison\n",
+    "print(da4)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "7b6033d9-cda5-4ac6-acf9-906ae6a22946",
+   "metadata": {},
+   "source": [
+    "_**NOTE**_: The asterisk (*) signifies that a coordinate is a primary dimension coordinate.\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "5327da03-1de8-4bb9-90b7-cf9535f9b47a",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#== Show ds1 in Html view"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "f2196608-d203-4334-9d85-06aeed77ce51",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "ds1"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "5b994337-a640-401c-80bd-83f6e46fc2e7",
+   "metadata": {},
+   "source": [
+    "_**NOTE**_: The indexes displayed in the HTML view highlight the internal structure and  \n",
+    "            are mainly useful for more advanced operations."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "069f891b-71eb-464a-a81a-323a174df9a8",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#== “The .info() method is used to display basic information on ds1 in a ‘ncdump’-like fashion.\n",
+    "#== Note: The .info() method is not available for DataArrays.\n",
+    "\n",
+    "ds1.info()\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "6148641c-fee3-4cf1-a99e-587e8bc4b48c",
+   "metadata": {},
+   "source": [
+    "#### D1.3: Access and inspect individual components of the Dataset"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "605586cc-3e1a-4f9d-a2a6-2542345ed134",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#== The data_vars attribute returns a container holding all the data variables in the dataset.\n",
+    "ds1.data_vars"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "481ec3cc-9eef-4def-895a-13b0288b98c6",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#== Retrieves the names of all data variables in the Dataset as a list\n",
+    "list(ds1.data_vars)\n",
+    "# alternative\n",
+    "list(ds1)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "94a18f3f-ebd4-41db-afe8-a6c22ea14f20",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#== Retrieves the name of the first data variable and print the attributes of this first data variable\n",
+    "first_varname = list(ds1)[0]\n",
+    "print(ds1[first_varname].attrs)                 #-- same result as hard-coded print(ds1.var1.attrs)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "d5e5bb6c-fabc-44e4-9ee2-15cb5cc69d9c",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#== Print the attributes of the var1 data variable\n",
+    "print(ds1.var1.attrs)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "a8001303-bac5-47c6-8f74-e898029b58f1",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#== Print the global attributes of the Dataset\n",
+    "ds1.attrs"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "5d40d18b-729f-4376-b027-184006d4761c",
+   "metadata": {},
+   "source": [
+    "#### D1.4: Add some global attributes to the Dataset"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "7ceb8fc3-2a39-4fe7-a9f3-87a1467813ce",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# Mandatory CF global attribute\n",
+    "ds1.attrs = {\"Conventions\": \"CF-1.8\"}\n",
+    "\n",
+    "# Recommended global attributes\n",
+    "global_attrs_recommended = {\n",
+    "    \"title\": \"Your Dataset Title\",\n",
+    "    \"institution\": \"Your Institution Name\",\n",
+    "    \"source\": \"Data source description\",\n",
+    "    \"history\": \"Description of processing history\",\n",
+    "    \"references\": \"References for data or methodology\",\n",
+    "    \"comment\": \"Any additional comments regarding the dataset\"\n",
+    "}\n",
+    "\n",
+    "# Append ds1 attributes with recommended attributes\n",
+    "ds1.attrs.update(global_attrs_recommended)\n",
+    "\n",
+    "# Display the updated Dataset\n",
+    "ds1.info()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "5a4e7573-ac8d-4e51-b7eb-24bd4a7651d8",
+   "metadata": {
+    "tags": []
+   },
+   "source": [
+    "***\n",
+    "\n",
+    "### D2 Showcase: Construct an xarray Dataset with xr.Dataset()\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "e76b3222-c5ee-4201-8e9f-651d94e28eb7",
+   "metadata": {},
+   "source": [
+    "#### D2.1: Create some dummy data"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "759302ad-9024-4c35-bfcd-cb0c7d006896",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "ntime, nlat, nlon = 7, 41, 21\n",
+    "# Create some dummy data for the data variables\n",
+    "mydata1 = np.random.rand(ntime, nlat, nlon) * 100  +  195.\n",
+    "mydata2 = np.clip((6.e+4 - (np.square(mydata1))) * 2.e-3, 0, 2.e+2)  #-- Values outside 0 and 200 are set to zero\n",
+    "# Create some dummy data for the coordinate variables (see also C2)\n",
+    "t_coords = xr.cftime_range(start=\"1990-01-01\", periods=ntime, freq=\"M\")\n",
+    "y_coords = np.linspace(10, 20, nlat)\n",
+    "x_coords = np.linspace(-160, -120, nlon)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "8abbc8a4-8495-49ba-aa96-22ded0069c28",
+   "metadata": {},
+   "source": [
+    "#### D2.2: Create individual components of the Dataset"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "9787c220-1fa7-40e2-bb69-d9ae29b3f313",
+   "metadata": {},
+   "source": [
+    "For simplicity, we will firstly create the individual components of the Dataset.  "
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "6eb7f0a8-efe3-487a-aff7-a5ebea0dcc2b",
+   "metadata": {
+    "tags": []
+   },
+   "source": [
+    "(a) \n",
+    "Create a dictionary named data_vars that defines the data variables for the xarray Dataset.   \n",
+    "The data variables share the same dimensions\n",
+    "\n",
+    "The syntax is: \n",
+    "```python\n",
+    "my_data_vars = {\n",
+    "     \"var_name_1\": (dimensions_1, data_1 [, attrs_1]),\n",
+    "     \"var_name_2\": (dimensions_2, data_2 [, attrs_2]),\n",
+    "     ...}```"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "3beceb26-74cb-488b-9339-7dec33d090ad",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "data_vars = {\"temp\": ([\"time\",\"lat\",\"lon\"], mydata1, {\"long_name\": \"Temperature\", \"units\":\"K\"}),\n",
+    "             \"prec\": ([\"time\",\"lat\",\"lon\"], mydata2, {\"standard_name\": \"thickness_of_rainfall_amount\", \"units\":\"m\"})}"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "3ea161cf-4aad-445e-bc7f-782544aad02b",
+   "metadata": {
+    "tags": []
+   },
+   "source": [
+    "(b) \n",
+    "Create a dictionary named coords that defines the coordinate variables for the xarray Dataset. "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "b9c130ba-574e-4fb8-9b26-749e0b162333",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "coords = {\"time\": t_coords,\n",
+    "          \"lat\":  y_coords,\n",
+    "          \"lon\":  x_coords}"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "6d455782-37d6-4251-b31a-1791eeb8bf75",
+   "metadata": {},
+   "source": [
+    "(c) \n",
+    "Create a dictionary named attrs that defines the global attributes of the Dataset."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "eb04fce1-122a-4d30-ba33-3c2d1bdec00a",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "attrs = {\"Conventions\": \"1.8\",\n",
+    "         \"history\": \"created on YYYY-MM-DD\",\n",
+    "         \"creator\": \"AH\",}"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "1fffc34f-1710-40f4-88ed-1cd346e0d047",
+   "metadata": {},
+   "source": [
+    "#### D2.3: Pass the individual components to the xr.Dataset() constructor call"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "14c482db-740d-46a8-8ee9-dfbf40ef4911",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "# Create the Dataset with data variables, coordinates, and dimensions\n",
+    "ds2 = xr.Dataset(data_vars=data_vars, coords=coords, attrs=attrs)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "46b0cd85-681a-4956-b75d-40899e2bae01",
+   "metadata": {},
+   "source": [
+    "#### D2.3: Inspect the Dataset"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "c238e08a-0361-4982-981e-f4567903d528",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "ds2"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "670920ca-d4d5-4e1b-b19a-9c12428e8788",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#### D2.4: Access and inspect individual components of the Dataset"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "6261fd03-19cf-42b7-b343-12f111fdaeb4",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#== List  names of all data variables in the Dataset ds2.\n",
+    "list(ds2)    #--same as list(ds2.data_vars)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "79c008ca-77f3-4ad2-a87c-d3b32d2746e4",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#== List names of all  variables (e.g. data and coordinate variables) in the Dataset ds2.\n",
+    "list(ds2.variables)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "81bb750f-ddc1-4c78-a063-a3eae89a0c96",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#== Access the data variable temp and check object type\n",
+    "myvar = \"temp\"\n",
+    "ds2_temp = ds2[myvar]\n",
+    "type(ds2_temp)\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "a1dee167-53f6-4fdd-adfc-0bb2ac628224",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#== Access the latitude coordinate variable associated with the temp variable.\n",
+    "ds2[myvar].lat        #-- this is identical to ds2.lat since lat is a global coordinate variable within the dataset"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "b2d8c444-162b-420f-a1ed-c1018fc5065e",
+   "metadata": {},
+   "source": [
+    "#### D2.4: Add a data variable and remove it"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "7fb07107-1308-42de-9eef-cdd0c0beac00",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "ds2[\"newvar\"] =  ds2[myvar][:,0,:]\n",
+    "ds2"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "c5916c5e-760c-4b9b-8d9c-def930854d4f",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# ds2[\"newvar\"].lat      # -- won't work since # ds2[\"newvar\"] doent have a lat dimension"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "048e197e-4e8d-4928-87e0-0a4ac93f3b68",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#== Get specific information about the dimensions of a Dataset and the temp data variable\n",
+    "print(f\"dimensions of Dataset:                                     {ds2.dims}\") \n",
+    "print(f\"dimensions of data variable of Dataset (=> DataArray):     {ds2[myvar].dims}\") "
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "55e34e30-74ad-47f5-a475-3230661d9e69",
+   "metadata": {},
+   "source": [
+    "_**NOTE**_: \n",
+    "When you access the dimensions of the entire dataset using ds2.dims, a Frozen dictionary is returned which is regular dictionary, but immutable.  \n",
+    "When you access the dimensions of a specific data variable (e.g., ds2[myvar].dims), a tuple of the dimension names for that particular variable is returned."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "55c0d329-a335-4623-8837-87ef5048cf66",
+   "metadata": {},
+   "source": [
+    "**How to remove the new data variable? What method is available for ds2 to do so?** "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "7d7cfb4a-e8a3-4692-abd6-e083f7babac6",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#dir(ds2)\n",
+    "# or more specific using string comparison with a search term on the dir(ds2) output\n",
+    "mysearch_term = \"var\"\n",
+    "[item for item in dir(ds2) if mysearch_term in item]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "aa78a9cb-3037-4f68-8941-19e21308b603",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "ds2.drop_vars?"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "10764121-d800-430a-941a-0c2f3993b38c",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "ds2 = ds2.drop_vars(\"newvar\")\n",
+    "ds2"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "2fe9f2dd-c701-4137-b1c1-bde828643ef2",
+   "metadata": {},
+   "source": [
+    "***\n",
+    "\n",
+    "### D3 Showcase: Construct an xarray Dataset with xr.Dataset() by merging two DataArrays\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "472a4098-89fc-4ab9-94ee-51bf36aa1775",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#== Generate two DataArrays that differ in dimensionality and dimension size.\n",
+    "#== Use the data and coordinate variable values from D2\n",
+    "\n",
+    "myda6 = xr.DataArray(mydata1, \n",
+    "                         name=\"var1\", \n",
+    "                         dims=[\"time\", \"lat\", \"lon\"], \n",
+    "                         coords=[t_coords, y_coords, x_coords]) #-- 3D DataArray\n",
+    "myda7 = xr.DataArray(mydata2[-1,1:-4,:], \n",
+    "                         name=\"var2\",\n",
+    "                         dims=[\"lat2\", \"lon\"], \n",
+    "                         coords=[y_coords[1:-4], x_coords],\n",
+    "                         attrs={\"units\":\"m\"})    #-- 2D DataArray"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "dc62ad35-29b3-40ad-9218-b3f123adfff1",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "#== Merge them with xr.merge(). This function call returns an xarray Dataset.\n",
+    "\n",
+    "ds3       = xr.merge([myda6, myda7])\n",
+    "\n",
+    "#== NOTE: Merging only works if each DataArray has a name attribute!\n",
+    "#   As alternative, you can merge DataArrays with the xr.Dataset() constructor call with specifying the name like, e.g.\n",
+    "#   ds = xr.Dataset({\"airtemp\": da5, \"var\": myda6})\n",
+    "#   This will overwrite the name attribute if the DataArray already had one."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "af24037b-a2d6-4bdf-9dcc-a4d6c0a2b7f7",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "print(ds3)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "1adb8c2a-4efa-42ab-a032-d32478fe9a70",
+   "metadata": {
+    "tags": []
+   },
+   "source": [
+    "_**NOTE**_: You can also merge a DataArray to an existing Dataset with `xr.merge()`."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "7804e5ed-81d1-493c-959c-865fc234de08",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "#== You can also merge a DataArray to an existing Dataset with `xr.merge()`.\n",
+    "ds3.data_vars\n",
+    "myda6.name\n",
+    "ds4 = xr.merge([ds3, myda6.rename(\"var3\")]) \n",
+    "print(ds4)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "c2a49623-f551-4bda-bfde-71e35e3c89e3",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "ds4b = xr.merge([ds4,myda6[:,-1,:-2].rename(\"var4\")])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "44ceae39-a892-4045-814b-a8147200e516",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "print(ds4b)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "4e3ba38f-7d5a-4417-b454-2e7b84cc26c2",
+   "metadata": {},
+   "source": [
+    "<br>\n",
+    "\n",
+    "______________________________________________________________________\n",
+    "# E) Indexing and slicing with xarray data: Showcases and Exercises\n",
+    "______________________________________________________________________\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "8ca2cef7-79dd-4a3e-b4f2-72d415dca6b4",
+   "metadata": {},
+   "source": [
+    "**Overview of the indexing options** <br>\n",
+    "see also: https://docs.xarray.dev/en/stable/user-guide/indexing.html#\n",
+    "\n",
+    "| Dimension lookup |  Index lookup |                 DataArray syntax                 |                  Dataset syntax                  |\n",
+    "|:-----------------|:--------------|:-------------------------------------------------|:-------------------------------------------------|\n",
+    "| Positional       | By integer    | `da[0, :, :]`                                    | not available                                    |\n",
+    "| Positional       | By label      | `da.loc[\"2001-01-01\", :, :]`                     | not available                                    |\n",
+    "| By name          | By integer    | `da.isel(time=0)` or <br>  `da[dict(time=0)]`        | `ds.isel(time=0)` or <br>  `ds[dict(time=0)`]        |\n",
+    "| By name          | By label      | `da.sel(time=\"2001-01-01\")` or <br>  `da.loc[dict(time=\"2001-01-01\")`] | `ds.sel(time=\"2001-01-01\"`) or <br>   `ds.loc[dict(time=\"2001-01-01\")]` |"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "d2bf2c7b-8e77-43be-8a1b-87c4497c90a2",
+   "metadata": {},
+   "source": [
+    "***\n",
+    "\n",
+    "### E1 Showcase: Indexing and Slicing on xarray DataArrays"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "38b5c1cd-ffd4-4d0a-8998-4457c70413b6",
+   "metadata": {},
+   "source": [
+    "For this showcase, we use the 2D DataArray myda7 from D3"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "11ddf0e1-b343-4f85-b693-91f0458ccb60",
+   "metadata": {},
+   "source": [
+    "#### E1.1: Index positional, by integer"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "8a41bcec-889e-45c5-9917-bb364c0e04fd",
+   "metadata": {},
+   "source": [
+    "Indexing can be done by the index(es) of the dimension(s).\n",
+    "\n",
+    "The general syntax for accessing values in a two-dimensional DataArray using two indices is:  \n",
+    "    `data_array [index_of_dim_0][index_of_dim_1]`   \n",
+    "or   \n",
+    "    `data_array [index_of_dim_0, index_of_dim_1]` \n",
+    "<br>\n",
+    "<br>\n",
+    "The general syntax for accessing values in a two-dimensional DataArray using a range of indices along one or more dimensions (_slicing_).<br>\n",
+    "`data_array[start_index_0:end_index_0][start_index_1:end_index_1]`  \n",
+    "or  \n",
+    "`data_array[start_index_0:end_index_0, start_index_1:end_index_1]`  \n",
+    "\n",
+    "<br>\n",
+    "\n",
+    "In two-dimensional arrays, the typical interpretation is that:\n",
+    "\n",
+    "•\t_rows_ correspond to the _first dimension_ (dimension 0)  \n",
+    "•\t_columns_ correspond to the _second dimension_ (dimension 1).\n",
+    "\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "285652a6-8adf-477e-8ec0-5fcee1c3b65e",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "#== Index the value from the myda7 DataArray at the index positions [1][0], \n",
+    "#== corresponding to the second row and the first column.\n",
+    "print(f\"myda7.shape= {myda7.shape}, myda7.dims={myda7.dims}\")\n",
+    "myda8 = myda7[1][0]\n",
+    "print(f\"myda8.data= {myda8.data}\")\n",
+    "print(f\"myda8.shape= {myda8.shape}, since a a scalar (0-dimensional) is returned\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "22f7b17d-8451-41b8-8ba9-bf28bd356282",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#== When a single index is provided for slicing, it operates along the first dimension.\n",
+    "#== Using myda7[0], the entire first row (i.e., the first dimension) of myda7 is selected,\n",
+    "#== which corresponds to extracting the first latitudinal band of the data.\n",
+    "myda7[0].shape\n",
+    "#== The same result can be obtained with a less efficient command due to redundant slicing:\n",
+    "myda7[0][:].shape"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "f3b60e2c-caf7-4e69-834a-a96deea1e0f6",
+   "metadata": {},
+   "source": [
+    "#### E1.2: Index by name, by integer"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "5c7d1fe5-406a-4adc-abd1-d83d392f125b",
+   "metadata": {},
+   "source": [
+    "Indexing with the `.isel()` method uses the dimension name and the integer index.<br>\n",
+    "Slicing with the `.isel()` method uses the dimension name and the integer index range indicated with `slice`."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "98d4c335-da25-4641-a265-2c44b8e4b0a7",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#== Select (index) the second row and the first column of the DataArray myda7\n",
+    "myda9 = myda7.isel(lat2=1, lon=0)             #-- equivalent to myda7[1][0]\n",
+    "print(f\"myda9.data= {myda9.data}\")\n",
+    "print(f\"myda9.shape= {myda9.shape}\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "ba382700-641d-43d0-bda2-109f2dcd232e",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#== Select (slice) the first and second row and the second and third column of myda7.\n",
+    "myda10 = myda7.isel(lat2=slice(0,2), lon=slice(1,3))          #-- equivalent to myda7[0:2, 1:3]\n",
+    "print(f\"myda10.data=\\n {myda10.data}\")\n",
+    "print(f\"myda10.shape= {myda10.shape}\")\n",
+    "print(f\"\\nCompare the original and sliced longitude coordinate values:\")\n",
+    "print(f\"myda10.lon.values=\\n {myda10.lon.values}\")\n",
+    "print(f\"myda7.lon.values=\\n {myda7.lon.values}\")\n",
+    "print(f\"myda7.lat2.values=\\n {myda7.lat2.values}\")\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "55ef5f86-3894-4c27-8863-9af0a3f7592f",
+   "metadata": {},
+   "source": [
+    "#### E1.3: Index by label, by name"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "0805cc04-a591-4822-9f78-24004942adec",
+   "metadata": {},
+   "source": [
+    "With the `.sel()` method, you can select specific values from a DataArray based on _coordinate values_.<br>\n",
+    "This can also be done with the `.loc[]` method."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "ff260cdf-bb0a-44d6-be0f-d3147074f4af",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#== Selecting a value from myda7 at the coordinates lat2=13.5 and lon=-156 \n",
+    "myda11 = myda7.sel(lat2=13.5, lon=-156.)  # By default, sel requires exact matches.\n",
+    "# ==  Alternatively, you can use .loc[]\n",
+    "#myda11 = myda7.loc[{\"lat2\": 13.5, \"lon\": -156}]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "5ed7c3ec-01e9-4cc3-93d7-6cdfe62e64a6",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "print(myda11)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "fc26f1be-c990-4c19-a321-4efcf02ee4d7",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#== Selecting a values from myda7 at the coordinates closest to lat2=14.69\n",
+    "#   using nearest neighbor interpolation (method=\"nearest\") with an optional tolerance of 1.0.\n",
+    "#   The tolerance restricts the maximum distance for inexact matches.\n",
+    "mylat2=14.69\n",
+    "myda12 = myda7.sel(lat2=mylat2, method=\"nearest\", tolerance=1.0)\n",
+    "#-- tolerance of 0.05 results in KeyError since no values found that match this criteria\n",
+    "print(f\"myda12.shape= {myda12.shape}\")\n",
+    "print(f\"myda12.lat2.values= {myda12.lat2.values}\")\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "74de761c-ab70-442c-b336-fa61d268bf91",
+   "metadata": {},
+   "source": [
+    "_**Note**_: In contrast to `.sel()`, `.loc[]` does not offer specifying a method!"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "8b485da1-d397-4c8a-9ef5-422ef880c49d",
+   "metadata": {},
+   "source": [
+    "#### E1.4: Index positional, by label"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "4feb56d0-ca44-421c-988f-b99d911a3cdd",
+   "metadata": {},
+   "source": [
+    "With the `.loc[]` method, you can select specific values from a DataArray based on coordinate values. "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "7bcb76c2-cc47-486d-9c3c-950f0d7f87b0",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "myda13 = myda7.loc[13.5, -156]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "fe2a1b3f-cdf2-4621-a6ed-9ba84cad2693",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "print(myda13)   #-- same as myda11"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "303ce799-6f25-4c6d-b78f-9b3f82c28242",
+   "metadata": {},
+   "source": [
+    "***\n",
+    "\n",
+    "### E2 Showcase: Indexing and Slicing on xarray Datasets"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "5f73845e-2463-49ca-9b1d-fc3590c742bf",
+   "metadata": {},
+   "source": [
+    "Indexing resp. slicing on xarray Datasets can only be done  \n",
+    "* _by name| by integer_\n",
+    "* _by name| by label_\n",
+    "\n",
+    "__Note__: Using these methods directly on the Dataset affects all contained data variables, applying the selection along the shared coordinates."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "f631e9e9-2e90-4e12-8c75-61ed3e987551",
+   "metadata": {},
+   "source": [
+    "For demonstration, we use the Dataset ds3 from Showcase D3. "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "d4a0dd89-9de5-4840-a4b9-d348c0a3d8eb",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "print(ds3)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "a63d7566-bf71-46ff-ad28-4b92b9dc7319",
+   "metadata": {},
+   "source": [
+    "#### E2.1: By name, by integer with `.isel()`"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "420c438a-96e8-404d-a4d9-fb67941d1446",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "ds3.isel(time=2, lat=slice(3,6), lon=slice(0,1))"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "03f27e2e-48c4-44da-b391-374efbfe8ace",
+   "metadata": {},
+   "source": [
+    "#### E2.2: By name, by label with `.sel()`"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "b8f52aab-1557-4d8a-ac37-7e61d4087f6a",
+   "metadata": {},
+   "source": [
+    "Using the .sel() method directly on the Dataset affects all contained data variables, applying the selection along the shared coordinates."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "5c9ad0ac-3342-45bb-a88e-4f7c0088d742",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# Extract data for the time step corresponding to 1990-03-31 from all variables in ds3\n",
+    "ds3.sel(time=\"1990-03-31\")   #-- returns a Dataset"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "ec321a82-e334-4b93-8d5e-5be1e9c18d3a",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#### E2.3: By name, by label with `.loc[]`"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "8e4d9626-b458-4e8e-8d05-71406df71c69",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "ds3.loc[{\"time\":\"1990-03-31\", \"lon\": slice(-150,-140)}]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "d97449e2-4fc7-4a05-bdb7-ae6d8c8e87b1",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#### E2.4: Indexing and slicing applied to a DataArray within the Dataset."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "2c2cbec2-118c-490a-976f-436cda185dfc",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# Extract data from the variable var1 for the time step 1990-03-31\n",
+    "# and certain longitude and latitude coordinate value ranges.\n",
+    "# The slice method hence applies to the DataArray within the Dataset. \n",
+    "ds3.var1.sel(time=\"1990-03-31\", lat=slice(12,13), lon=slice(-150, -147))\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "62498905-f033-4c0c-a28c-3ec1bd6f3b95",
+   "metadata": {},
+   "source": [
+    "\n",
+    "### E3 Exercise: Indexing and Slicing"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "9c22ebd0-af37-4643-93a7-c7784d79d333",
+   "metadata": {},
+   "source": [
+    "Extract some data from the Dataset ds3 from Showcase D3 using<br>\n",
+    "   1.         .isel()\n",
+    "   2.         .sel()\n",
+    "   3.         .loc[]\n",
+    "Apply these functions both on the entire Dataset and data variables.  \n",
+    "Which method do you like better `.sel()` or `.loc[]`?"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "3370f2ba-13c4-4336-afd8-07d06099b77c",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# 1\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "56992a3b-c3ee-46c3-bd2d-ea6acae788ab",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# 2\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "9b6f873b-6cb1-40c0-9322-7212d938310c",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# 3\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "edcaf3ab-4bc3-4520-ab00-06b92cc3ead9",
+   "metadata": {},
+   "source": [
+    "#### E3 Solution Exercise"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "c374864d-09fa-4c28-a124-e5f47a2f5f68",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "# 1 on the Dataset\n",
+    "ds3.isel(lat=2,lon=0,time=1).values"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "93112261-32ca-4907-a17b-1c1922aa42a1",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "# 1 on a data variable\n",
+    "ds3.var2.isel(lat2=2,lon=0).values"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "9818597a-f2b6-453f-88da-f1a9f752d0e3",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "# 2 on the Dataset\n",
+    "ds3.sel(lat2 = 18.5, time = \"1990-02-28\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "e452778c-d4db-4435-9e98-a9b3342529e9",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "# 2 on the data variable\n",
+    "ds4.var2.sel(lat2 = slice(18,19.2))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "2e8be05b-6657-4c4f-856d-07b7e2d1fb6b",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "# 3 on the Dataset\n",
+    "ds4.loc[{\"lat2\": [10.5,18.25], \"time\": \"1990-02-28\"}]"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "bdc2e17f-0636-4e7a-a4b1-b73a8661a257",
+   "metadata": {},
+   "source": [
+    "***\n",
+    "## F) Save, open, and read files with xarray\n",
+    "\n",
+    "***\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "566e78fe-7c7d-41c1-a645-74a9aefe15ce",
+   "metadata": {},
+   "source": [
+    "***\n",
+    "\n",
+    "### F1 Showcase: Saving xarray DataArrays or Datasets as netCDF file"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "b68c908b-b3ec-45d2-9bfd-04b08d50b677",
+   "metadata": {},
+   "source": [
+    "\n",
+    "`to_netcdf()` allows you to save a Dataset or DataArray to a netCDF file.<br> \n",
+    "The default mode is \"w\" (write), but you can specify other modes such as \"a\" (append) or \"r\" (read) as arguments to the method call. "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "fa43249d-bf4e-4196-8081-2d78f64a4d6c",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#== Save the xarray Dataset ds3 from Showcase D3.\n",
+    "ds3.to_netcdf(\"ds3.nc\")    #-- (\"ds3.nc\") "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "1c1afb8d-1433-4040-bdee-32ba1e9381fc",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#== Have an overview look at the netCDF file content with ncdump (Shell command available on Levante)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "719e1bdc-33d9-4e7d-b18f-997efb317472",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "!ncdump -h ds3.nc"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "0d6f0c0c-e08f-49c9-90cd-996022f4a797",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "#== Slice the ds3 prior saving it to ds3.nc. Overwrite existing ds3.nc\n",
+    "ds3.isel(lat = slice(3,9), lat2 = slice(10,14)).to_netcdf(\"ds3.nc\", mode=\"w\") "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "94c5b03e-b362-495c-b543-2787a8cd06a8",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "!ncdump -h ds3.nc"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "aaaf5cba-b948-4e3e-8c99-cb975d88a71e",
+   "metadata": {},
+   "source": [
+    "***\n",
+    "\n",
+    "### F2 Showcase:  Open and read a netCDF file with xarray"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "a0188112-5f2f-49a0-9bcc-46919e05c49d",
+   "metadata": {},
+   "source": [
+    "xarray provides the function `xr.open_dataset()` to open a file with the file format netCDF, GRIB, HDF5, or Zarr.  \n",
+    "Default format is netCDF.<br>\n",
+    "    `ds_in = xr.open_dataset(\"infile.nc\")`<br>\n",
+    "is the same as<br>\n",
+    "    `ds_in = xr.open_dataset(\"infile.nc\", engine=\"netCDF4\")`"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "61db211a-a491-45c7-a55b-6ac77386d5e0",
+   "metadata": {},
+   "source": [
+    "<div class=\"alert alert-info\">\n",
+    "    <b>xarray is Lazy:</b> By default, xarray performs lazy loading: With open_dataset, it only loads the metadata <br>\n",
+    "    (such as variable names, dimensions, and attributes) from the netCDF file into memory, without loading the actual data values.<br>\n",
+    "The data values are loaded into memory only when you explicitly access them or perform operations that require accessing the data.<br>\n",
+    "    <b>Lazy loading helps saving memory and enhancing the performance.</b>\n",
+    "</div>\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "7f2dc515-49b3-4cdc-89fe-81131bdf520b",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#== Open (lazy-loading) the netCDF file created in Showcase 13.\n",
+    "xr.open_dataset(\"ds3.nc\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "15f07932-b524-4212-b8b0-4853f13f1709",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#== Open the netCDF file created in Showcase F1 and load the data into memory.\n",
+    "ds5 = xr.open_dataset(\"ds3.nc\").load()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "87065f99-cffd-40b5-8831-7fad9686c293",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "ds5.info"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "1c3ba127-ba60-4b15-bd73-5e1b4d88f791",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#== In case you wish to remove the reference to the Dataset ds5, use:\n",
+    "#   del(ds5)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "1ad5e56e-190c-44b2-af52-2243f7b4c4b2",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#== Open ds3.nc and then lazily loading only the variable \"var1\" it.\n",
+    "ds6 = xr.open_dataset(\"ds3.nc\")[[\"var1\"]]    #-- [[\"var1\", \"var2\"]] if two variables"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "bd175f57-528d-4c01-b1fd-63c85cabdda4",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "ds6"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "2424d12e-3433-42f2-9d39-9edd24d23290",
+   "metadata": {},
+   "source": [
+    "***\n",
+    "\n",
+    "### F3 Showcase:  Open and read a GRIB file with xarray\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "c496f4c5-f38e-44a9-80f1-ffc8ba003fce",
+   "metadata": {},
+   "source": [
+    "By default, the xr.open_dataset() constructor call selects the _engine_ (_i.e. library or backend used to read the file_) to open the file  \n",
+    "based on the file name extension or attempts to infer it the file format based on the file contents. <br>\n",
+    "For GRIB files, the engine is usually `cfgrib`."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "b4a0b3a0-7cfa-4651-889b-4f00a283af94",
+   "metadata": {},
+   "source": [
+    "_**NOTE**_: when opening a GRIB file with cfgrib as the engine in xarray, an index file (.idx) is typically created or used if available. If an available index file is incompatible with the GRIB file, xarray issues a warning indicating that the index file is being ignored. "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "81ffa90e-d4b8-46e9-a361-5a08bfa51f99",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "ds7 = xr.open_dataset(\"../data/MET9_IR108_cosmode_0909210000.grb2\")\n",
+    "# same as \n",
+    "# ds7 = xr.open_dataset(\"../data/MET9_IR108_cosmode_0909210000.grb2\", engine=\"cfgrib\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "d11b846a-c077-4afa-ac08-8208bf8d9cfc",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#-- List the data variables\n",
+    "print(f\"{ds7.data_vars} \\n {ds7.coords}\")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "69443de1-d3cd-4f80-a76e-9a392dd73d11",
+   "metadata": {},
+   "source": [
+    "***\n",
+    "\n",
+    "### F4 Showcase: Open and read a multiple netCDF files at once with xarray\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "43ffefd1-b40b-4c9e-8901-3f127d1b2e9e",
+   "metadata": {},
+   "source": [
+    "*xarray* provides the function `xr.open_mfdataset()` to read multiple files in one step as a single Dataset.<br>\n",
+    "When using `xr.open_mfdataset()`, it recommended to have **dask** enabled (by having dask installed in your environment).<br>\n",
+    "**Dask** is utilized to load and process the data in a parallelized manner. "
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "f5559513-bb2b-43d6-9054-4438261d2619",
+   "metadata": {},
+   "source": [
+    "For demonstration, we open three netCDF files _precip_day01.nc, precip_day02.nc, and precip_day03.nc_, each containing the data of one day in 6 hour intervals. "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "1cc4ab67-5444-4c1b-bfe7-6733e94a96f8",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#== Open the files with xr.open_mfdataset\n",
+    "ds8 = xr.open_mfdataset(\"../data/precip_day*.nc\")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "d3cc7d3b-b518-4c4c-90c1-8dae6025d314",
+   "metadata": {
+    "tags": []
+   },
+   "source": [
+    "_**NOTE**_: By default, xr.open_mfdataset will concatenate the dimensions of the Datasets along which they overlap.\n",
+    "In this example, the data are concatenated along the time dimension.\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "8592569c-470c-4fa2-bbc1-428c30c1c366",
+   "metadata": {},
+   "source": [
+    "<div class=\"alert alert-info\">\n",
+    "    <b>Dask is Very Lazy!</b> <br>\n",
+    "    When Dask is used to load the data, the data are loaded as dask.array objects.\n",
+    "</div>"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "7ef53a23-a737-48a8-aaa3-f73467276e4e",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#== Look at the description of the data variable of ds8. \n",
+    "#== You will see that precip is represented as dask.array object.\n",
+    "ds8"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "f52cfbbb-e6f1-4beb-81f8-c5df80e9cbc4",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#== Indexing dask.array objects in ds8 will not directly display the exact values, \n",
+    "#== but instead provide a preview of the data.\n",
+    "#== To access a specific point in the array, you need to load the data into memory first.\n",
+    "ds8.precip[1,4,5]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "be82b529-91ec-4106-ab5f-296fae96a563",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "#== Loading the accessed data point as xarray DataArray. \n",
+    "ds8.precip[1,4,5].load()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "0d740310-1c01-4360-a10e-e07287c7153e",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "#== Alternative: loading the accessed data point as numpy array.\n",
+    "ds8.precip[1,4,5].values"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "74da3f4d-efa8-404a-8835-a34acb65ac04",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#== You can also load the entire Dataset or individual data variables.\n",
+    "ds8.load().head(2)\n",
+    "# or\n",
+    "#ds8.precip.load().head(2)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "e3e2cb78-16a5-408e-9972-009a24d6728e",
+   "metadata": {},
+   "source": [
+    "<br>\n",
+    "\n",
+    "***\n",
+    "\n",
+    "### F5 Exercise: Open a netCDF file with `xr.DataArray`\n",
+    "\n",
+    "<br>"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "300aba36-5fea-4a1e-bf0a-cbb794cbe21e",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# 1. Open the file \"../data/rectilinear_grid_2D.nc\" with xarray\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "cfb0bb07-a02a-4dbf-8b90-993bba39b55b",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# 2. List all data variables of the Dataset as a list\n",
+    "\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "83afc2ad-daf3-485b-bcc4-75ecf430eba0",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# 3. List all data variables and coordinate variables of the Dataset as a list\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "d935b15e-23f0-4bbe-ac76-16d83c65eaee",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# 4. Lazy load the first variable of the list, print it with head(2) \n",
+    "#    Then load it into memory while assigning it to a variable da_rg. \n",
+    "#    Print it again with head(2) \n",
+    "\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "429b43e4-2321-4cf0-bc58-48bd459468f3",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# 5. Plot the first timestep of da_rg\n",
+    "\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "60b1ce25-8fcb-49b4-a3a1-758b174363ad",
+   "metadata": {
+    "tags": []
+   },
+   "source": [
+    "#### Solution Exercise 5"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "e87e1214-104e-42ae-9d1d-98808a2e2270",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "# 1.\n",
+    "ds9 = xr.open_dataset(\"../data/rectilinear_grid_2D.nc\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "8e257ce3-11b0-4384-be47-e53a9cd423d0",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "# 2.\n",
+    "list(ds9.data_vars)\n",
+    "list(ds9.keys())\n",
+    "list(ds9)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "5890c3f2-9810-4657-a441-640efbd9c656",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "# 3.\n",
+    "list(ds9.variables)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "9d657253-7029-48d8-a661-1b36bcc1fe4a",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "# 4.\n",
+    "ds9[list(ds9)[0]].head(2)\n",
+    "print(\"*\"*100)\n",
+    "da_rg = ds9[list(ds9)[0]].load()\n",
+    "da_rg.head(2)\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "f2b329a4-2bad-4960-8659-2377e99e6651",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "# 5.\n",
+    "da_rg.isel(time=0).plot();"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "10b0181a-9436-40fb-b771-9ff8ff8d9773",
+   "metadata": {},
+   "source": [
+    "***\n",
+    "## G) Appendix\n",
+    "***"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "bfe73a3d-f6d1-4f2c-bfb8-0862cf88449f",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    },
+    "tags": []
+   },
+   "source": [
+    "***\n",
+    "\n",
+    "### G1 Showcase: From numpy arrays to xarray DataArrays"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "306dcc84-6851-412e-a682-d76ae5140e94",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    },
+    "tags": []
+   },
+   "source": [
+    "You can directly convert a numpy array into an xarray DataArray type by using it as input for xarray\"s function `xr.DataArray`. "
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "f97a43cf-b52c-435c-8d8c-7cce87240b24",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    },
+    "tags": []
+   },
+   "source": [
+    "We use the _atmosphere water vapor content_ data from the file `../data/prw.dat` by loading it with numpy."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "56fb99e3",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#== Show the first 5 lines of the ascii input file.\n",
+    "!head -5 ../data/prw.dat"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "a21e702a-ad00-4b37-a0fc-9396c9e831f5",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#== Read columns 1 to 3 of the input file while skipping the header.\n",
+    "prw_data     = np.loadtxt(\"../data/prw.dat\", usecols=(1,2,3),skiprows=1)         #-- data are read in as float64\n",
+    "prw_stations = np.loadtxt(\"../data/prw.dat\", usecols=0, skiprows=1, dtype=\"U10\") #-- data are read in as string"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "169713cf-7534-412a-9dbe-689273cc2ef4",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#== Get the shape of the numpy ndarray prw_data.\n",
+    "prw_data.shape"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "0bb6b812-310d-4fcf-8bc7-f7e80d04349e",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#== Get the first 4 rows of the prw_data.\n",
+    "prw_data[:4, :]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "c0e6134e-fdd4-4433-8541-e6ddf14bbe88",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#== Convert the numpy ndarray prw_data into an xarray DataArray.\n",
+    "prw_da1 = xr.DataArray(prw_data)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "dff469f0-9b16-4de3-9bc6-1359b2dead4e",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "#== Get the first four elements (rows) of the xarray DataArray using slicing.\n",
+    "prw_da1[:4, :]"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "f74124c7-7eac-421c-a055-ac1aa8e16399",
+   "metadata": {},
+   "source": [
+    "The comparison of `prw_da1[:4, :])` and `prw_data[:4, :]` illustrates that when slicing a xarray DataArray,the structure and metadata are preserved. In contrast, slicing a numpy array results in a new numpy array without additional metadata."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "a3b2fbc0-e14a-4a39-b2f3-341ebda4a564",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "#  As an alternative to prw_da1[:4, :], you can use the functionality `head` on the xarray DataArray.\n",
+    "#  This functionality is not available for a numpy ndarray.\n",
+    "#  prw_da1.head(4)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "624a60e6-b2a9-4612-bcfd-60dcdc3f22a5",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "print(f\"type of prw_data: {type(prw_data)}; type of prw_da1: {type(prw_da1)};\")\n",
+    "print(f\"the data structure wrapped in the xarray DataArray is: {type(prw_da1.data)}\")         \n",
+    "print(f\"the data type of the elements of the wrapped data is: {prw_da1.data.dtype}\") \n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "6cbfc94d-9f3e-4a5d-b6d3-6a0881afc976",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "source": [
+    "Unlike a numpy array, the xarray DataArray can differentiate the variable of interest as a *data variable* (`prw_da1.data`) from *coordinate* variables. This is because the xarray DataArray has the following components:\n",
+    "- **dimensions**: Named dimensions that define the structure of the array (`prw_da1.dims`).\n",
+    "- **coordinates**: Variables associated with each dimension, providing context and labeling (`prw_da1.coords`).\n",
+    "- **attributes**: Additional metadata describing the array or its components (`prw_da1.attrs`).\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "c18c8d09-e4f1-4ca5-a7cf-57705c8d2b59",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "#print(f\"data variable: {prw_da1.data}\")\n",
+    "print(f\"coordinate variable: {prw_da1.coords}\") \n",
+    "print(f\"dimension names: {prw_da1.dims}\")\n",
+    "print(f\"data variable name: {prw_da1.name}\")\n",
+    "print(f\"data variable metadata: {prw_da1.attrs}\")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "0a613a89-fb8a-4726-9f9f-8f5f9c3720a2",
+   "metadata": {},
+   "source": [
+    "When created without specific parameters in the xr.DataArray function call, prw_da1 defaults to empty coordinates, default dimension names (\"dim_0\", \"dim_1\"), and lacks a data variable name or associated metadata."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "9bfca75f-a2a6-4435-bec2-29772d2d164a",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "***\n",
+    "\n",
+    "### G2 Showcase: Specify the structure/parameters during the `xarray.DataArray()` function call"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "945a83fa-dfb1-429f-80c1-5e410db2426f",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "Create a new xarray DataArray called prw_da2:\n",
+    "1. The **data variable** corresponds to the first column of the numpy array `prw_data`.\n",
+    "2. We have one dimension (**dims**) which represents individual stations; we name it **_Station_**. <br>\n",
+    "   By default, it is an index running from 0 to the length of a column minus 1.\n",
+    "3. The **coords** are the first and second columns of the numpy array `prw_data`. We want to call them `lat` and `lon`. <br>\n",
+    "   They have the same dimensions as the data array, namely **_Station_**. \n",
+    "   The general syntax for declaring the coordinate is: <br>\n",
+    "   `coords = {coords_name: (dimension_name, coordinate_values)}`\n",
+    "4. The **name** of the data variable is **prw**.\n",
+    "5. In the **attrs**, we can store variable attributes like **_units_**. The **standard_name** of prw is **_atmosphere_mass_content_of_water_vapor_**; <br> the corresponding canonical units are **_kg m-2_**."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "6f65ead5-64a1-48c4-b981-7cf253a7c748",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "prw_da2 = xr.DataArray(prw_data[:,2],\n",
+    "                           dims=[\"Station\"],\n",
+    "                           coords={\"lat\":(\"Station\", prw_data[:,0]),\n",
+    "                                   \"lon\":(\"Station\", prw_data[:,1])},\n",
+    "                           name=\"prw\",\n",
+    "                           attrs={\"units\":\"kg m-2\",\n",
+    "                                  \"standard_name\":\"atmosphere_mass_content_of_water_vapor\"})"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "9831c927-346e-4f1d-80d0-0f910be7856d",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "prw_da2"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "588b23fa-9c50-40bc-9a58-2dd4d50cb7fa",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "outputs": [],
+   "source": [
+    "print(f\"data variable (sliced): {prw_da2.data[:8]}\")\n",
+    "print(f\"dimension names:        {prw_da2.dims}\")\n",
+    "\n",
+    "print(f\"coordinate variable:\\n  {prw_da2.coords}\") \n",
+    "\n",
+    "print(f\"name of DataArray (coresponding to data variable name):            {prw_da2.name}\")\n",
+    "print(f\"metadata of DataArray (corresponding to data variable metadata):\\n {prw_da2.attrs}\")\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "39ea8ad8-345f-4b7c-84ea-d85f1b257918",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "outputs": [],
+   "source": [
+    "print(f\"shape the DataArray:      {prw_da2.shape}\")\n",
+    "print(f\"size of the DataArray:    {prw_da2.sizes}\") \n",
+    "# Note: sizes returns a eturns an immutable dictionary-like object, often referred to as a \"frozen\" object in xarray."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "6689de19-4091-40d7-b32e-13e7fcf7f189",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "prw_da2.plot(figsize=(3, 2));"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "4e8900b7-b4ef-4512-b161-3513be782a78",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    },
+    "tags": []
+   },
+   "source": [
+    "***\n",
+    "\n",
+    "### G3 Exercise: xr.DataArray\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "e0717073",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "outputs": [],
+   "source": [
+    "# 1. Create a two dimensional numpy called prw_data_2d with the size `len(prw_data)` x `len(prw_data)` \n",
+    "#    and assign `NaN` values to the entire array.\n",
+    "#    Use np.Nan and np.full() or np.empty().\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "4baf6447-377d-4abb-88ac-4dbc55efa73c",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# 2. On the diagonal of the quadratic array, insert the values of prw_data. Use a for loop.\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "28e4d302-85ab-4d2f-a67c-0b0e474e4d96",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# 3. Convert the numpy array to a xarray DataArray named prw_da3.\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "34840ed8-55d0-40ab-9e43-08cb415216cf",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# 4. Show prw_da3 by plotting.\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "7271d6a0-f926-4e0f-b08c-96acb3a392ec",
+   "metadata": {},
+   "source": [
+    "#### G3 Solution Exercise"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "2dbcd161-a5a2-4d98-a6fd-17bfb44ec015",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# 1.\n",
+    "#prw_data.shape\n",
+    "prw_data_2d  = np.full([len(prw_data), len(prw_data)], np.nan) #-- np.full creates an array with a specified value\n",
+    "# Alternatives:\n",
+    "# prw_data_2d = np.empty([len(prw_data),len(prw_data)]) * np.nan"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "daf21374-4bb0-4305-9479-853d90b422f3",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# 2. \n",
+    "for i in range(0, len(prw_data)):\n",
+    "    prw_data_2d[i,i] = prw_data[i,2]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "beb4c823-b603-4232-b4c6-cdf8cdce5533",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# 3. \n",
+    "prw_da3 = xr.DataArray(prw_data_2d)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "b97580ea-645d-4d83-924d-0d43dfce82b5",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# 4.\n",
+    "prw_da3.plot();"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "a03fe6f2-dabe-4075-bb6b-babb461d0d21",
+   "metadata": {},
+   "source": [
+    "***\n",
+    "\n",
+    "### G4 Showcase: Add a new coordinate variable to an xarray DataArray\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "131bdc62-72fa-4855-9672-5c0d0e2c6168",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#== Add a new coordinate variable named \"station_name\" in the prw_da2 DataArray. \n",
+    "#== This new coordinate variable contains the station names provided in the prw_stations array.\n",
+    "prw_da2[\"station_name\"] = xr.DataArray(prw_stations, dims=\"Station\")\n",
+    "prw_da2.head(5)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "cdf8fc95-481d-479d-a3a5-07391939961f",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#== When plotting, we can now use the new coordinate variable to label the x-axis.\n",
+    "prw_da2.plot(x=\"station_name\", figsize=(16,4));\n",
+    "plt.xticks(rotation=90);\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "a8140a54-ba7e-4ca2-b716-b33c0d5089f1",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "source": [
+    "### G5 Showcase: Gridding station data with  `xr.DataArray`\n",
+    "\n",
+    "\n",
+    "To put the station data prw_data from showcase 1 on a regular lat lon grid, use the following steps: "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "fb50f9bb-2f3a-481f-bf84-71b557dc7126",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    },
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "#== 1. Define the latitudes and longitudes for the regular grid using np.linspace, \n",
+    "#      with the minimum and maximum values of latitude and longitude from the station coordinates as bounds.\n",
+    "\n",
+    "nlat, nlon = 25, 50\n",
+    "latitudes  = np.linspace(min(prw_data[:,0]), max(prw_data[:,0]), num=nlat)\n",
+    "longitudes = np.linspace(min(prw_data[:,1]), max(prw_data[:,1]), num=nlon)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "8df7b816-5ca3-4d6a-ae28-1589f18790cd",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    },
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "#== 2.  Create a 2D grid of NaN values with the size (nlat,nlon).\n",
+    "data_grid = np.full((nlat, nlon), np.nan)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "adb6c672-dba4-49ec-b203-19c2a393fa8d",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    },
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "#== 3. Find the indices for assigning data values to the grid.\n",
+    "lat_indices = np.searchsorted(latitudes, prw_data[:,0])\n",
+    "lon_indices = np.searchsorted(longitudes, prw_data[:,1])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "cc4f13b1-52bd-4714-8dd5-c0cbaea621d4",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "#== 4.  Assign the data values to the corresponding grid points.\n",
+    "data_grid[lat_indices, lon_indices] = prw_data[:,2]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "5455c807-8de5-48f7-b63c-ef9f3dc836c2",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "#== 5. Create the DataArray with latitude and longitude coordinates.\n",
+    "pwr_da4 = xr.DataArray(data_grid, \n",
+    "                  coords={\"lat\": latitudes, \"lon\": longitudes}, \n",
+    "                  dims=[\"lat\", \"lon\"])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "8bc4cfd3-0449-440e-a982-d4340aee0582",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "#== 6. Plot the new DataArray\n",
+    "\n",
+    "pwr_da4.plot();"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "ca3fa0a8-05a5-4d3e-9004-bd8127dcf9f9",
+   "metadata": {},
+   "source": [
+    "### G6 Showcase: Combine of xarray plotting with more advanced matplotlib/cartopy features for creating maps"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "524efad7-29fd-4ce8-852b-a0417d7fe7d4",
+   "metadata": {},
+   "source": [
+    "In this showcase, we use the regularly gridded station data pwr_da4 from Showcase G5."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "50700c8c-a189-4ca3-9438-b123813c3321",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "skip"
+    },
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "import cartopy.crs as ccrs\n",
+    "proj    = ccrs.PlateCarree()                            # choose map projection\n",
+    "fig, ax = plt.subplots(figsize=(7, 9), subplot_kw={\"projection\":proj})\n",
+    "ax.set_extent([-102, -90, 29, 41], proj)\n",
+    "img = ax.stock_img()                                    # add satellite image as background\n",
+    "img.set_alpha(0.4)                                      # adjust background image transparency\n",
+    "ax.gridlines(draw_labels=True, color=\"None\", zorder=0)  # turn on axis label, turn off gridlines\n",
+    "ax.coastlines()                                         # add coastlines\n",
+    "pwr_da4.plot(cmap=\"turbo\", cbar_kwargs={\"shrink\": 0.5,  \"pad\": 0.1});"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "1bdff15d-30c9-4d11-af8a-4b3ec9b3cc77",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "source": [
+    "<br>\n",
+    "\n",
+    "***\n",
+    "\n",
+    "### G7 Exercise: `xr.DataArray` Modify pwr_da4\n",
+    "\n",
+    "<br>"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "d8de744d-f91c-4d20-b3b5-96baba2facf2",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# 1. print the variable attributes and add a variable long_name attribute \n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "56cc7d97-ee01-4bbf-a0c6-65f1171574b4",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# 2. print the variable name and change it\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "6ebad36e-a623-43ca-a8dd-c8316f1a84db",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# 3. print the dimension names.\n",
+    "#    rename them into lat1 and lon and assign the returned object as pwr_da5\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "15c68af8-08cb-4cd5-89c6-c716140b800f",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# 4. add a standard_name and units attribute to the coordinate variable lon1 in pwr_da5\n",
+    "#    and print the new attributes\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "7585ab2f-97c6-4ef5-a7a5-bc1f182965d4",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# 5. exchange the lat1 coordinate variable values by a numpy array;\n",
+    "#    print the first 5 values of the new lat1 coordinate variable \n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "3b92e684-221c-441d-86d6-28306e58e491",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# 6. set the values of the first 6 rows and first 6 columns of \n",
+    "#    the pwr_data_da4 DataArray to -50\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "80b66dc3-905e-45ed-8adf-481f0bb9e4b2",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# 7. plot the modified DataArray \n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "4987e40e-fcf0-4e50-8afd-a7c67ee5cb8d",
+   "metadata": {},
+   "source": [
+    "#### G7 Solution Exercise"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "7f3ba964-0336-4001-9c8c-d67acd4bc1e5",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# 1.\n",
+    "print(f\"variable attributes is: {pwr_da4.attrs}\")\n",
+    "pwr_da4.attrs={\"long_name\": \"water vapor content\"}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "f4bf07af-ad05-4c6c-9b86-6fc3e32e599a",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# 2.\n",
+    "print(f\"variable name is: {pwr_da4.name}\")\n",
+    "pwr_da4.name = \"prw\""
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "634519ad-778b-41fe-836d-41fa1b05e72a",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# 3.\n",
+    "print(f\"dimension names are:   {pwr_da4.dims}\")\n",
+    "pwr_da5 = pwr_da4.rename({\"lat\": \"lat1\", \"lon\": \"lon1\"})\n",
+    "print(f\"dimension names are:   {pwr_da5.dims}\")\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "7db4bf3e-a677-4bce-9e9b-3b9f59cec5a1",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# 4.\n",
+    "pwr_da5[\"lon1\"].attrs={\"standard_name\": \"longitude\", \"units\":\"degrees_east\"}\n",
+    "pwr_da5.lon1.attrs"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "666f635d-e91d-45da-8c2e-5e352fd4a35a",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "# 5. \n",
+    "newlats = np.linspace(0,10, pwr_da5.sizes[\"lat1\"])\n",
+    "pwr_da5.coords[\"lat1\"] = newlats\n",
+    "print(f\"first 5 values of new lat1 coordinate variable are: {pwr_da5.lat1.head(5).values}\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "36e9732f-6e09-49ae-aecd-47be33c2485b",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# 6. \n",
+    "pwr_da5[:6, :6] = -50"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "b3e77203-d69e-4b36-9f6c-52bbad99310e",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# 7.\n",
+    "pwr_da5.plot();"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "e9fe3bc1-3a11-400f-ad52-cf70230e40f8",
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "markdown",
+   "id": "61d518b4-7410-46f3-9480-cee9bb1e06e5",
+   "metadata": {},
+   "source": [
+    "***\n",
+    "\n",
+    "### G8 Showcase: Expand the dimensions of a xarray DataArray\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "f109a858-3383-405f-8794-eaf160745328",
+   "metadata": {},
+   "source": [
+    "With `DataArray.expand_dims()`, you can add a new dimension, e.g. time, to a DataArray A. This function call returns a new DataArray object. \n",
+    "In the new, expanded DataArray B, the original values of A are repeated along the new dimension (e.g. time). In other words, the original values of A are broadcasted along this new dimension to match the shape of the resulting DataArray B."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "f1e51bca-4e86-42dc-9915-89054f10e6ec",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#== Add a time dimension with values 1 and 2 to the pwr_da5 DataArray.\n",
+    "time = [1, 2]\n",
+    "pwr_da6 = pwr_da5.expand_dims({\"time\":time}, axis=0)   \n",
+    "# Note: axis=0 ensures that the new dimension is inserted as the first dimension, \n",
+    "# so that the resulting dimension order is time,lat,lon."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "50af7478-0672-48b3-a5a8-6df1f8202aa8",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "#== Compare the dimensionality and shape of the old and new DataArray:\n",
+    "\n",
+    "print(f\" dims before:  {pwr_da5.dims}\\n dims after:   {pwr_da6.dims}\")\n",
+    "print(\"====\"*20)\n",
+    "print(f\" shape before: {pwr_da5.shape}\\n shape after:  {pwr_da6.shape}\")\n",
+    "print(\"====\"*20)\n",
+    "print(f\" sizes before: {pwr_da5.sizes}\\n sizes after:  {pwr_da6.sizes}\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "6da14987-2dcb-4291-bb57-efa2e88e7c7e",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "#== Compare if the data values at the first time step are equal to the second time step. \n",
+    "\n",
+    "import numpy.testing as npt\n",
+    "try:\n",
+    "    npt.assert_array_equal(pwr_da6.isel(time=0).data, pwr_da6.isel(time=1).data)\n",
+    "    print(\"Equal\")\n",
+    "except AssertionError:\n",
+    "    print(\"Not equal\")"
+   ]
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "1 Python 3 (based on the module python3/2023.01)",
+   "language": "python",
+   "name": "python3_2023_01"
+  },
+  "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.10.10"
+  },
+  "toc-autonumbering": false
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
-- 
GitLab