Repository: GoLP-IST/nata (language: python)

Issue:
Notebooks as examples
Nata should have some example notebooks. We should store these notebooks in `examples` and focus on covering common topics that complement the API documentation (mentioned in #135).


Discussion / hints:
Make sure the notebooks work well with the current version. When we start including the GitHub action runners, we should also focus that the notebooks are executed to ensure that no errors are raised.

Fix patch:
diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
index 9ffd254..4b8ebe8 100644
--- a/.devcontainer/devcontainer.json
+++ b/.devcontainer/devcontainer.json
@@ -2,9 +2,6 @@
 	"name": "natadev",
 	"context": "..",
 	"dockerFile": "../Dockerfile",
-	"settings": {
-		"terminal.integrated.shell.linux": null
-	},
 	"extensions": [
 		"ms-python.python",
 		"ms-python.vscode-pylance",
diff --git a/.devcontainer/postCreateScript.sh b/.devcontainer/postCreateScript.sh
index 4ff80dc..c380ff4 100755
--- a/.devcontainer/postCreateScript.sh
+++ b/.devcontainer/postCreateScript.sh
@@ -11,3 +11,6 @@ poetry run pip install ipdb
 
 echo -e "\e[104m>>> Installing pytest-watch \e[0m"
 poetry run pip install pytest-watch
+
+echo -e "\e[104m>>> Installing graphviz \e[0m"
+poetry run pip install graphviz
diff --git a/.gitignore b/.gitignore
index 70615ae..5f49457 100644
--- a/.gitignore
+++ b/.gitignore
@@ -189,10 +189,6 @@ $RECYCLE.BIN/
 # venv module files
 .venv/
 
-# examples/data directory should not be commited to git
-# use other services to download it - in general it should
-# vary large and shouldn't be commited to GitHub
-examples/data
-
 # vscode
 .vscode
+examples/mydask.png
diff --git a/Dockerfile b/Dockerfile
index 84e7bd9..4c51169 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -36,6 +36,11 @@ RUN \
   && cd .. \
   && rm -rf hdf5-${HDF5_VERSION} hdf5-${HDF5_VERSION}.tar.bz2
 
+# graphviz
+RUN \
+  apt-get update \
+  && apt-get install -y graphviz
+
 # Pip
 RUN \
   pip install poetry \
diff --git a/examples/GridDataset.ipynb b/examples/GridDataset.ipynb
deleted file mode 100644
index 153c2c4..0000000
--- a/examples/GridDataset.ipynb
+++ /dev/null
@@ -1,464 +0,0 @@
-{
- "cells": [
-  {
-   "cell_type": "code",
-   "execution_count": 1,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "%load_ext autoreload\n",
-    "%autoreload 2"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "# GridDataset\n",
-    "\n",
-    "Nata represents grids by the `GridDataset` container which can be imported by running"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 2,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "import sys\n",
-    "\n",
-    "import numpy as np\n",
-    "\n",
-    "from nata.containers import GridDataset\n",
-    "from nata.containers import GridAxes\n",
-    "from nata.containers import Axis"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "The next sections discuss the API of `GridDataset`, how to create a grid using the `GridDataset` class, and the basic properties of those objects. In the following, any reference to a grid refers to a instance while `GridDataset` represent the class definition."
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "## Note on grids\n",
-    "\n",
-    "Nata has two ways to create a grid, using an array-like object or from an path as the basis. The creation of a grid from an array is a common way to enrich a general numpy array, a dask array, or any array like object with the functionality nata adds on top of arrays. It is also the recommended way to create an grid object.\n",
-    "\n",
-    "<div class=\"alert alert-block alert-warning\">\n",
-    "    Grid objects can be created by calling <code>GridDataset(...)</code> and instantiating it from the class object directly. This use is discouraged and is recommended for advanced users only.\n",
-    "</div>\n",
-    "\n",
-    "## Using array-like objects\n",
-    "\n",
-    "Creating a grid from an array-like object can be done by calling the class method `GridDataset.from_array`"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 3,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/html": [
-       "<div>GridDataset</div><table style='margin-left: 1rem;'><tr><td style='font-weight: bold; text-align: left;'>name</td><td style='text-align: left;'>unnamed</td></tr><tr><td style='font-weight: bold; text-align: left;'>label</td><td style='text-align: left;'>unlabeled</td></tr><tr><td style='font-weight: bold; text-align: left;'>unit</td><td style='text-align: left;'>''</td></tr><tr><td style='font-weight: bold; text-align: left;'>backend</td><td style='text-align: left;'>None</td></tr></table><details><summary>Array Properties</summary><table style='margin-left: 1rem;'><tr><td style='font-weight: bold; text-align: left;'>ndim</td><td style='text-align: left;'>2</td></tr><tr><td style='font-weight: bold; text-align: left;'>shape</td><td style='text-align: left;'>(2, 3)</td></tr><tr><td style='font-weight: bold; text-align: left;'>dtype</td><td style='text-align: left;'>int64</td></tr></table></details>"
-      ],
-      "text/plain": [
-       "GridDataset[unnamed]"
-      ]
-     },
-     "execution_count": 3,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "grid = GridDataset.from_array([[1, 2, 3], [3, 4, 5]])\n",
-    "grid"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "## Naming grids, labelling grids, and attaching units to grids"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 4,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/html": [
-       "<div>GridDataset</div><table style='margin-left: 1rem;'><tr><td style='font-weight: bold; text-align: left;'>name</td><td style='text-align: left;'>my_new_name</td></tr><tr><td style='font-weight: bold; text-align: left;'>label</td><td style='text-align: left;'>My New Label</td></tr><tr><td style='font-weight: bold; text-align: left;'>unit</td><td style='text-align: left;'>some unit</td></tr><tr><td style='font-weight: bold; text-align: left;'>backend</td><td style='text-align: left;'>None</td></tr></table><details><summary>Array Properties</summary><table style='margin-left: 1rem;'><tr><td style='font-weight: bold; text-align: left;'>ndim</td><td style='text-align: left;'>2</td></tr><tr><td style='font-weight: bold; text-align: left;'>shape</td><td style='text-align: left;'>(2, 3)</td></tr><tr><td style='font-weight: bold; text-align: left;'>dtype</td><td style='text-align: left;'>int64</td></tr></table></details>"
-      ],
-      "text/plain": [
-       "GridDataset[my_new_name]"
-      ]
-     },
-     "execution_count": 4,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "grid = GridDataset.from_array([[1, 2, 3], [3, 4, 5]], name=\"my_new_name\", label=\"My New Label\", unit=\"some unit\")\n",
-    "grid"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "And modified, e.g. for `name`"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 5,
-   "metadata": {},
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "grid.name = 'some_new_name'\n"
-     ]
-    }
-   ],
-   "source": [
-    "grid.name = \"some_new_name\"\n",
-    "print(f\"{grid.name = }\")"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 6,
-   "metadata": {},
-   "outputs": [
-    {
-     "name": "stderr",
-     "output_type": "stream",
-     "text": [
-      "Argument 'name' has to be an identifier\n"
-     ]
-    }
-   ],
-   "source": [
-    "try:\n",
-    "    grid = GridDataset.from_array([[1, 2, 3], [3, 4, 5]], name=\"some invalid name\")\n",
-    "except ValueError as exc:\n",
-    "    print(exc, file=sys.stderr)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 7,
-   "metadata": {},
-   "outputs": [
-    {
-     "name": "stderr",
-     "output_type": "stream",
-     "text": [
-      "New name has to be an identifier\n"
-     ]
-    }
-   ],
-   "source": [
-    "try:\n",
-    "    grid.name = \"some invalid name\"\n",
-    "except ValueError as exc:\n",
-    "    print(exc, file=sys.stderr)"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "## Axes of grids"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "Calling this method uses an implicit instantiation. It means that nata uses default values for the common properties, e.g. name, label, axes, to ensure consistancy when dealing with grid objects. This properties can be changed by assigning a new value. Alternatively, a grid can be created by using an explicit instantiation, e.g. passing arguments to the function call."
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 8,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/html": [
-       "<div>GridDataset</div><table style='margin-left: 1rem;'><tr><td style='font-weight: bold; text-align: left;'>name</td><td style='text-align: left;'>unnamed</td></tr><tr><td style='font-weight: bold; text-align: left;'>label</td><td style='text-align: left;'>unlabeled</td></tr><tr><td style='font-weight: bold; text-align: left;'>unit</td><td style='text-align: left;'>''</td></tr><tr><td style='font-weight: bold; text-align: left;'>backend</td><td style='text-align: left;'>None</td></tr></table><details><summary>Array Properties</summary><table style='margin-left: 1rem;'><tr><td style='font-weight: bold; text-align: left;'>ndim</td><td style='text-align: left;'>2</td></tr><tr><td style='font-weight: bold; text-align: left;'>shape</td><td style='text-align: left;'>(2, 3)</td></tr><tr><td style='font-weight: bold; text-align: left;'>dtype</td><td style='text-align: left;'>int64</td></tr></table></details>"
-      ],
-      "text/plain": [
-       "GridDataset[unnamed]"
-      ]
-     },
-     "execution_count": 8,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "grid = GridDataset.from_array(\n",
-    "    [[1, 2, 3], [3, 4, 5]],\n",
-    "    indexable_axes=[[0.0, 0.1, 0.2], [10, 20, 30]],\n",
-    ")\n",
-    "grid"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 9,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/html": [
-       "<div>GridAxes</div><table style='margin-left: 1rem;'><tr><td style='font-weight: bold; text-align: left;'>indexable</td><td style='text-align: left;'>axis0, axis1</td></tr><tr><td style='font-weight: bold; text-align: left;'>hidden</td><td style='text-align: left;'>-</td></tr></table>"
-      ],
-      "text/plain": [
-       "GridAxes<indexable=('axis0', 'axis1'), hidden=()>"
-      ]
-     },
-     "execution_count": 9,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "grid.axes"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "If the argument `time` is provideded, then the first axis for the grid axes correspond to the time axis. Alternatively, an iteration axis can also be provided as another temporal axis."
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 10,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/html": [
-       "<div>GridAxes</div><table style='margin-left: 1rem;'><tr><td style='font-weight: bold; text-align: left;'>indexable</td><td style='text-align: left;'>axis0, axis1</td></tr><tr><td style='font-weight: bold; text-align: left;'>hidden</td><td style='text-align: left;'>axis2</td></tr></table>"
-      ],
-      "text/plain": [
-       "GridAxes<indexable=('axis0', 'axis1'), hidden=('axis2',)>"
-      ]
-     },
-     "execution_count": 10,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "grid = GridDataset.from_array(\n",
-    "    [[1, 2, 3], [3, 4, 5]],\n",
-    "    hidden_axes=[[123, 345, 678]],\n",
-    ")\n",
-    "grid.axes"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 11,
-   "metadata": {},
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "np.array(grid.axes['axis0'].as_numpy()) = array([0, 1])\n",
-      "np.array(grid.axes['axis1'].as_numpy()) = array([0, 1, 2])\n",
-      "np.array(grid.axes['axis2'].as_numpy()) = array([123, 345, 678])\n"
-     ]
-    }
-   ],
-   "source": [
-    "print(f\"{np.array(grid.axes['axis0'].as_numpy()) = }\")\n",
-    "print(f\"{np.array(grid.axes['axis1'].as_numpy()) = }\")\n",
-    "print(f\"{np.array(grid.axes['axis2'].as_numpy()) = }\")"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 12,
-   "metadata": {},
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "grid.axes[0] = Axis(name='axis0', label='unlabeled', unit='')\n",
-      "grid.axes[1] = Axis(name='axis1', label='unlabeled', unit='')\n"
-     ]
-    }
-   ],
-   "source": [
-    "print(f\"{grid.axes[0] = }\")\n",
-    "print(f\"{grid.axes[1] = }\")"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 13,
-   "metadata": {},
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "[[0 1 2]\n",
-      " [1 2 3]\n",
-      " [1 2 3]\n",
-      " [1 2 3]\n",
-      " [1 2 3]]\n",
-      "\n",
-      "grid0.axes[0].as_numpy() = array([0, 1, 1, 1, 1])\n",
-      "grid0.axes[1].as_numpy() = array([[-10,  -5,   5],\n",
-      "       [ 10,   0,   1],\n",
-      "       [ 10,   0,   1],\n",
-      "       [ 10,   0,   1],\n",
-      "       [ 10,   0,   1]])\n"
-     ]
-    }
-   ],
-   "source": [
-    "grid0 = GridDataset.from_array([0, 1, 2], indexable_axes=[Axis([-10, -5, 5], name=\"axis0_grid0\")], hidden_axes=[0])\n",
-    "grid1 = GridDataset.from_array([1, 2, 3], indexable_axes=[Axis([10, 0, 1], name=\"axis0_grid0\")], hidden_axes=[1])\n",
-    "\n",
-    "grid0.append(grid1)\n",
-    "grid0.append(grid1)\n",
-    "grid0.append(grid1)\n",
-    "grid0.append(grid1)\n",
-    "\n",
-    "print(f\"{grid0.as_numpy()}\\n\")\n",
-    "print(f\"{grid0.axes[0].as_numpy() = }\")\n",
-    "print(f\"{grid0.axes[1].as_numpy() = }\")"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 14,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/html": [
-       "<div>GridDataset</div><table style='margin-left: 1rem;'><tr><td style='font-weight: bold; text-align: left;'>name</td><td style='text-align: left;'>charge</td></tr><tr><td style='font-weight: bold; text-align: left;'>label</td><td style='text-align: left;'>\\rho</td></tr><tr><td style='font-weight: bold; text-align: left;'>unit</td><td style='text-align: left;'>e \\omega_p^2/ c^2</td></tr><tr><td style='font-weight: bold; text-align: left;'>backend</td><td style='text-align: left;'>osiris_4.4.4_grid_hdf5</td></tr></table><details><summary>Array Properties</summary><table style='margin-left: 1rem;'><tr><td style='font-weight: bold; text-align: left;'>ndim</td><td style='text-align: left;'>3</td></tr><tr><td style='font-weight: bold; text-align: left;'>shape</td><td style='text-align: left;'>(105, 440, 275)</td></tr><tr><td style='font-weight: bold; text-align: left;'>dtype</td><td style='text-align: left;'>float32</td></tr></table></details>"
-      ],
-      "text/plain": [
-       "GridDataset[charge]"
-      ]
-     },
-     "execution_count": 14,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "grid_charge = GridDataset.from_path(\"data/charge/charge-electrons-*.h5\")\n",
-    "grid_charge"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "## Array properties \n",
-    "\n",
-    "<div class=\"alert alert-block alert-info\">\n",
-    "Any reference to an array assumes numpy like arrays.\n",
-    "</div>\n",
-    "\n",
-    "Each `GridDataset` acts as it would be an array by providing common array properties. This properties are read-only and can be modified by array functions, e.g., `np.reshape`."
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 15,
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "grid.shape = (2, 3)\n",
-      "grid.ndim  = 2\n",
-      "grid.dtype = dtype('int64')\n"
-     ]
-    }
-   ],
-   "source": [
-    "print(f\"{grid.shape = }\")\n",
-    "print(f\"{grid.ndim  = }\")\n",
-    "print(f\"{grid.dtype = }\")"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "In addition to the array properties, "
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "Also an extra information about the unit for `GridDataset` and by default it is empty. However, it behaves similar to a numpy array by providing properties like `.shape`, `.ndim` and `.dtype`."
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {
-    "tags": []
-   },
-   "source": [
-    "\n",
-    "\n",
-    "In general, a `GridDataset` is expected to behave like an array."
-   ]
-  }
- ],
- "metadata": {
-  "kernelspec": {
-   "display_name": "Python 3",
-   "language": "python",
-   "name": "python3"
-  },
-  "language_info": {
-   "codemirror_mode": {
-    "name": "ipython",
-    "version": 3
-   },
-   "file_extension": ".py",
-   "mimetype": "text/x-python",
-   "name": "python",
-   "nbconvert_exporter": "python",
-   "pygments_lexer": "ipython3",
-   "version": "3.8.9"
-  }
- },
- "nbformat": 4,
- "nbformat_minor": 4
-}
diff --git a/examples/data/grids/grid-1d-0.h5 b/examples/data/grids/grid-1d-0.h5
new file mode 100755
index 0000000..142341c
Binary files /dev/null and b/examples/data/grids/grid-1d-0.h5 differ
diff --git a/examples/data/grids/grid-1d-1.h5 b/examples/data/grids/grid-1d-1.h5
new file mode 100755
index 0000000..1f4d065
Binary files /dev/null and b/examples/data/grids/grid-1d-1.h5 differ
diff --git a/examples/data/grids/grid-1d-2.h5 b/examples/data/grids/grid-1d-2.h5
new file mode 100755
index 0000000..8a6f8eb
Binary files /dev/null and b/examples/data/grids/grid-1d-2.h5 differ
diff --git a/examples/data/grids/grid-1d-3.h5 b/examples/data/grids/grid-1d-3.h5
new file mode 100755
index 0000000..cc4ae85
Binary files /dev/null and b/examples/data/grids/grid-1d-3.h5 differ
diff --git a/examples/data/grids/grid-1d-4.h5 b/examples/data/grids/grid-1d-4.h5
new file mode 100755
index 0000000..11eb659
Binary files /dev/null and b/examples/data/grids/grid-1d-4.h5 differ
diff --git a/examples/data/grids/grid-1d-5.h5 b/examples/data/grids/grid-1d-5.h5
new file mode 100755
index 0000000..763b89b
Binary files /dev/null and b/examples/data/grids/grid-1d-5.h5 differ
diff --git a/examples/data/particles/left-0.h5 b/examples/data/particles/left-0.h5
new file mode 100755
index 0000000..00aaff4
Binary files /dev/null and b/examples/data/particles/left-0.h5 differ
diff --git a/examples/data/particles/left-1.h5 b/examples/data/particles/left-1.h5
new file mode 100755
index 0000000..48fd23d
Binary files /dev/null and b/examples/data/particles/left-1.h5 differ
diff --git a/examples/data/particles/left-2.h5 b/examples/data/particles/left-2.h5
new file mode 100755
index 0000000..9b4fc28
Binary files /dev/null and b/examples/data/particles/left-2.h5 differ
diff --git a/examples/data/particles/left-3.h5 b/examples/data/particles/left-3.h5
new file mode 100755
index 0000000..e07f547
Binary files /dev/null and b/examples/data/particles/left-3.h5 differ
diff --git a/examples/data/particles/left-4.h5 b/examples/data/particles/left-4.h5
new file mode 100755
index 0000000..9e2536a
Binary files /dev/null and b/examples/data/particles/left-4.h5 differ
diff --git a/examples/data/particles/left-5.h5 b/examples/data/particles/left-5.h5
new file mode 100755
index 0000000..c760a8c
Binary files /dev/null and b/examples/data/particles/left-5.h5 differ
diff --git a/examples/working with grids.ipynb b/examples/working with grids.ipynb
new file mode 100644
index 0000000..c43ae68
--- /dev/null
+++ b/examples/working with grids.ipynb
@@ -0,0 +1,814 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Natas representation of grids\n",
+    "\n",
+    "Nata has two type of representation for grids, `GridArray` and `GridDataset`. Both types are **array-like containers** which have a common interface for\n",
+    "\n",
+    "- Annotations (`.name`, `.label`, `.unit`)\n",
+    "- Plugins (`.plot`, `.fft`, ...)\n",
+    "\n",
+    "and both can be created **from a file** (using `.from_path`) or **from an array-like object** (using `.from_array`)."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from nata.containers import GridArray\n",
+    "from nata.containers import GridDataset"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## How to create GridArray and GridDataset"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Create an `GridArray` from a numpy array with annotations."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/markdown": [
+       "\n",
+       "| **GridArray** | |\n",
+       "| ---: | :--- |\n",
+       "| **name**  | unnamed |\n",
+       "| **label** | unlabeled |\n",
+       "| **unit**  | '' |\n",
+       "| **shape** | (4, 8) |\n",
+       "| **dtype** | float64 |\n",
+       "| **time**  | None |\n",
+       "| **axes**  | Axis(axis0), Axis(axis1) |\n",
+       "\n"
+      ],
+      "text/plain": [
+       "GridArray<shape=(4, 8), dtype=float64, time=None, axes=(Axis(axis0), Axis(axis1))>"
+      ]
+     },
+     "execution_count": 2,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "import numpy as np\n",
+    "\n",
+    "example_array = np.arange(32, dtype=np.float64).reshape((4, 8))\n",
+    "\n",
+    "grid = GridArray.from_array(example_array)\n",
+    "grid"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "By default nata will provide some default parameters when creating a container object. This can be changed at creation"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/markdown": [
+       "\n",
+       "| **GridArray** | |\n",
+       "| ---: | :--- |\n",
+       "| **name**  | some_name |\n",
+       "| **label** | some label |\n",
+       "| **unit**  | some unit |\n",
+       "| **shape** | (4, 8) |\n",
+       "| **dtype** | float64 |\n",
+       "| **time**  | 10.0 |\n",
+       "| **axes**  | Axis(a1), Axis(a2) |\n",
+       "\n"
+      ],
+      "text/plain": [
+       "GridArray<shape=(4, 8), dtype=float64, time=10.0, axes=(Axis(a1), Axis(a2))>"
+      ]
+     },
+     "execution_count": 3,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "from nata.containers import Axis\n",
+    "\n",
+    "grid = GridArray.from_array(\n",
+    "    example_array,\n",
+    "    name=\"some_name\",\n",
+    "    label=\"some label\",\n",
+    "    unit=\"some unit\",\n",
+    "    time=10.0,\n",
+    "    axes=(\n",
+    "        Axis.from_array([0, 1, 2, 3], name=\"a1\"),\n",
+    "        Axis.from_array(np.arange(8) - 10, name=\"a2\"),\n",
+    "    )\n",
+    ")\n",
+    "grid"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "or by changing each property individually"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/markdown": [
+       "\n",
+       "| **GridArray** | |\n",
+       "| ---: | :--- |\n",
+       "| **name**  | some_new_name |\n",
+       "| **label** | some new label |\n",
+       "| **unit**  | some new unit |\n",
+       "| **shape** | (4, 8) |\n",
+       "| **dtype** | float64 |\n",
+       "| **time**  | 10.0 |\n",
+       "| **axes**  | Axis(a1), Axis(a2) |\n",
+       "\n"
+      ],
+      "text/plain": [
+       "GridArray<shape=(4, 8), dtype=float64, time=10.0, axes=(Axis(a1), Axis(a2))>"
+      ]
+     },
+     "execution_count": 4,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "grid.name = \"some_new_name\"\n",
+    "grid.label = \"some new label\"\n",
+    "grid.unit = \"some new unit\"\n",
+    "grid"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "The `GridArray` represent a grid at **one** specific time step"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "grid.time.shape = ()\n",
+      "grid.axes[0].shape = (4,)\n",
+      "grid.axes[1].shape = (8,)\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(f\"{grid.time.shape = }\")\n",
+    "print(f\"{grid.axes[0].shape = }\")\n",
+    "print(f\"{grid.axes[1].shape = }\")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "but the `GridDataset` represents a grid at **different time steps**"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/markdown": [
+       "\n",
+       "| **GridDataset** | |\n",
+       "| ---: | :--- |\n",
+       "| **name**  | unnamed |\n",
+       "| **label** | unlabeled |\n",
+       "| **unit**  | '' |\n",
+       "| **shape** | (4, 8) |\n",
+       "| **dtype** | float64 |\n",
+       "| **time**  | [0 1 2 3] |\n",
+       "| **axes**  | Axis(time), Axis(axis0) |\n",
+       "\n"
+      ],
+      "text/plain": [
+       "GridDataset<shape=(4, 8), dtype=float64, time=[0 1 2 3], axes=(Axis(time), Axis(axis0))>"
+      ]
+     },
+     "execution_count": 6,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "grid_ds = GridDataset.from_array(example_array)\n",
+    "grid_ds"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "grid_ds.shape = (4, 8)\n",
+      "grid_ds.time.shape = (4,)\n",
+      "grid_ds.axes[0].shape = (4,)\n",
+      "grid_ds.axes[1].shape = (4, 8)\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(f\"{grid_ds.shape = }\")\n",
+    "print(f\"{grid_ds.time.shape = }\")\n",
+    "print(f\"{grid_ds.axes[0].shape = }\")\n",
+    "print(f\"{grid_ds.axes[1].shape = }\")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Reading from path\n",
+    "\n",
+    "Grids can be created by using the `.from_path` method."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from nata import examples"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Here are some example grid files:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "total 48\n",
+      "-rwxrwxrwx 1 natadev natadev 7336 Aug 18  2020 grid-1d-0.h5\n",
+      "-rwxrwxrwx 1 natadev natadev 7336 Nov  7  2019 grid-1d-1.h5\n",
+      "-rwxrwxrwx 1 natadev natadev 7336 Nov  7  2019 grid-1d-2.h5\n",
+      "-rwxrwxrwx 1 natadev natadev 7336 Nov  7  2019 grid-1d-3.h5\n",
+      "-rwxrwxrwx 1 natadev natadev 7336 Nov  7  2019 grid-1d-4.h5\n",
+      "-rwxrwxrwx 1 natadev natadev 7336 Nov  7  2019 grid-1d-5.h5\n"
+     ]
+    }
+   ],
+   "source": [
+    "!ls -l {examples.grids}"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "To create a `GridArray` from **one file** simply use the `.from_path` method"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/markdown": [
+       "\n",
+       "| **GridArray** | |\n",
+       "| ---: | :--- |\n",
+       "| **name**  | e1 |\n",
+       "| **label** | E_1 |\n",
+       "| **unit**  | m_e c \\omega_p e^{-1} |\n",
+       "| **shape** | (120,) |\n",
+       "| **dtype** | float32 |\n",
+       "| **time**  | 0.0 |\n",
+       "| **axes**  | Axis(x1) |\n",
+       "\n"
+      ],
+      "text/plain": [
+       "GridArray<shape=(120,), dtype=float32, time=0.0, axes=(Axis(x1))>"
+      ]
+     },
+     "execution_count": 10,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "one_grid = GridArray.from_path(examples.grids / \"grid-1d-0.h5\")\n",
+    "one_grid"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "or create a `GridDataset` from **several files**"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/markdown": [
+       "\n",
+       "| **GridDataset** | |\n",
+       "| ---: | :--- |\n",
+       "| **name**  | e1 |\n",
+       "| **label** | E_1 |\n",
+       "| **unit**  | m_e c \\omega_p e^{-1} |\n",
+       "| **shape** | (6, 120) |\n",
+       "| **dtype** | float32 |\n",
+       "| **time**  | [ 0. 10. 20. 30. 40. 50.] |\n",
+       "| **axes**  | Axis(time), Axis(x1) |\n",
+       "\n"
+      ],
+      "text/plain": [
+       "GridDataset<shape=(6, 120), dtype=float32, time=[ 0. 10. 20. 30. 40. 50.], axes=(Axis(time), Axis(x1))>"
+      ]
+     },
+     "execution_count": 11,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "multiple_grids = GridDataset.from_path(examples.grids / \"*\")\n",
+    "multiple_grids"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Indexing"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Nata's container support object indexing, e.g. indexing along the temporal axis"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/markdown": [
+       "\n",
+       "| **GridArray** | |\n",
+       "| ---: | :--- |\n",
+       "| **name**  | e1 |\n",
+       "| **label** | E_1 |\n",
+       "| **unit**  | m_e c \\omega_p e^{-1} |\n",
+       "| **shape** | (120,) |\n",
+       "| **dtype** | float32 |\n",
+       "| **time**  | 20.0 |\n",
+       "| **axes**  | Axis(x1) |\n",
+       "\n"
+      ],
+      "text/plain": [
+       "GridArray<shape=(120,), dtype=float32, time=20.0, axes=(Axis(x1))>"
+      ]
+     },
+     "execution_count": 12,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "multiple_grids[2]"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "or indexing along the spatial axis"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/markdown": [
+       "\n",
+       "| **GridDataset** | |\n",
+       "| ---: | :--- |\n",
+       "| **name**  | e1 |\n",
+       "| **label** | E_1 |\n",
+       "| **unit**  | m_e c \\omega_p e^{-1} |\n",
+       "| **shape** | (3, 29) |\n",
+       "| **dtype** | float32 |\n",
+       "| **time**  | [ 0. 20. 40.] |\n",
+       "| **axes**  | Axis(time), Axis(x1) |\n",
+       "\n"
+      ],
+      "text/plain": [
+       "GridDataset<shape=(3, 29), dtype=float32, time=[ 0. 20. 40.], axes=(Axis(time), Axis(x1))>"
+      ]
+     },
+     "execution_count": 13,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "multiple_grids[::2, 10:-25:3]"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Getting the data stored"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "numpy.ndarray"
+      ]
+     },
+     "execution_count": 14,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "type(multiple_grids.to_numpy())"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "array([ 0.03756667, -0.02527247, -0.05402965, -0.0644568 , -0.08836149,\n",
+       "       -0.13276438, -0.16449456, -0.18726616, -0.21021022, -0.17068724,\n",
+       "       -0.0675886 ,  0.05470179,  0.15090737,  0.16236047,  0.1385156 ],\n",
+       "      dtype=float32)"
+      ]
+     },
+     "execution_count": 15,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "multiple_grids[-1, 10:25].to_numpy()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Data in nata is stored in dask array. This allow "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<table>\n",
+       "<tr>\n",
+       "<td>\n",
+       "<table>\n",
+       "  <thead>\n",
+       "    <tr><td> </td><th> Array </th><th> Chunk </th></tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr><th> Bytes </th><td> 2.88 kB </td> <td> 480 B </td></tr>\n",
+       "    <tr><th> Shape </th><td> (6, 120) </td> <td> (1, 120) </td></tr>\n",
+       "    <tr><th> Count </th><td> 18 Tasks </td><td> 6 Chunks </td></tr>\n",
+       "    <tr><th> Type </th><td> float32 </td><td> numpy.ndarray </td></tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "</td>\n",
+       "<td>\n",
+       "<svg width=\"170\" height=\"84\" style=\"stroke:rgb(0,0,0);stroke-width:1\" >\n",
+       "\n",
+       "  <!-- Horizontal lines -->\n",
+       "  <line x1=\"0\" y1=\"0\" x2=\"120\" y2=\"0\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"0\" y1=\"5\" x2=\"120\" y2=\"5\" />\n",
+       "  <line x1=\"0\" y1=\"11\" x2=\"120\" y2=\"11\" />\n",
+       "  <line x1=\"0\" y1=\"17\" x2=\"120\" y2=\"17\" />\n",
+       "  <line x1=\"0\" y1=\"23\" x2=\"120\" y2=\"23\" />\n",
+       "  <line x1=\"0\" y1=\"28\" x2=\"120\" y2=\"28\" />\n",
+       "  <line x1=\"0\" y1=\"34\" x2=\"120\" y2=\"34\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Vertical lines -->\n",
+       "  <line x1=\"0\" y1=\"0\" x2=\"0\" y2=\"34\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"120\" y1=\"0\" x2=\"120\" y2=\"34\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Colored Rectangle -->\n",
+       "  <polygon points=\"0.0,0.0 120.0,0.0 120.0,34.50101617379934 0.0,34.50101617379934\" style=\"fill:#ECB172A0;stroke-width:0\"/>\n",
+       "\n",
+       "  <!-- Text -->\n",
+       "  <text x=\"60.000000\" y=\"54.501016\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" >120</text>\n",
+       "  <text x=\"140.000000\" y=\"17.250508\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" transform=\"rotate(0,140.000000,17.250508)\">6</text>\n",
+       "</svg>\n",
+       "</td>\n",
+       "</tr>\n",
+       "</table>"
+      ],
+      "text/plain": [
+       "dask.array<stack, shape=(6, 120), dtype=float32, chunksize=(1, 120), chunktype=numpy.ndarray>"
+      ]
+     },
+     "execution_count": 16,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "multiple_grids.to_dask()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Grid containers behave like numpy arrays"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 17,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/markdown": [
+       "\n",
+       "| **GridArray** | |\n",
+       "| ---: | :--- |\n",
+       "| **name**  | example |\n",
+       "| **label** | \\chi |\n",
+       "| **unit**  | '' |\n",
+       "| **shape** | (4,) |\n",
+       "| **dtype** | int64 |\n",
+       "| **time**  | None |\n",
+       "| **axes**  | Axis(axis0) |\n",
+       "\n"
+      ],
+      "text/plain": [
+       "GridArray<shape=(4,), dtype=int64, time=None, axes=(Axis(axis0))>"
+      ]
+     },
+     "execution_count": 17,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "example = GridArray.from_array([0, 1, 4, 9], name=\"example\", label=\"\\chi\")\n",
+    "example"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 18,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "array([0., 1., 2., 3.])"
+      ]
+     },
+     "execution_count": 18,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "sqrt_example = np.sqrt(example)\n",
+    "sqrt_example.to_numpy()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "While numpy functions are directly supported by using numpy's dispatch mechanism, annotations are not conserved"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 19,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/markdown": [
+       "\n",
+       "| **GridArray** | |\n",
+       "| ---: | :--- |\n",
+       "| **name**  | unnamed |\n",
+       "| **label** | unlabeled |\n",
+       "| **unit**  | '' |\n",
+       "| **shape** | (4,) |\n",
+       "| **dtype** | float64 |\n",
+       "| **time**  | None |\n",
+       "| **axes**  | Axis(axis0) |\n",
+       "\n"
+      ],
+      "text/plain": [
+       "GridArray<shape=(4,), dtype=float64, time=None, axes=(Axis(axis0))>"
+      ]
+     },
+     "execution_count": 19,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "sqrt_example"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "To cover this special cases, nata introduces plugins. They are handy helper for repeatable tasks"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 20,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/markdown": [
+       "\n",
+       "| **GridArray** | |\n",
+       "| ---: | :--- |\n",
+       "| **name**  | sqrt_example |\n",
+       "| **label** | \\sqrt(\\chi) |\n",
+       "| **unit**  | '' |\n",
+       "| **shape** | (4,) |\n",
+       "| **dtype** | float64 |\n",
+       "| **time**  | None |\n",
+       "| **axes**  | Axis(axis0) |\n",
+       "\n"
+      ],
+      "text/plain": [
+       "GridArray<shape=(4,), dtype=float64, time=None, axes=(Axis(axis0))>"
+      ]
+     },
+     "execution_count": 20,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "from nata.plugins import register_container_plugin\n",
+    "\n",
+    "@register_container_plugin(GridArray, name=\"sqrt\")\n",
+    "def sqrt_for_grids(data):\n",
+    "    result = np.sqrt(data)\n",
+    "    result.name = \"sqrt_\" + data.name\n",
+    "    result.label = f\"\\sqrt({data.label})\"\n",
+    "    \n",
+    "    return result\n",
+    "\n",
+    "example.sqrt()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 21,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[<matplotlib.lines.Line2D at 0xffff801207c0>]"
+      ]
+     },
+     "execution_count": 21,
+     "metadata": {},
+     "output_type": "execute_result"
+    },
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<Figure size 432x288 with 1 Axes>"
+      ]
+     },
+     "metadata": {
+      "needs_background": "light"
+     },
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "nata_grid = GridArray.from_array([0, 1, 0, 2])\n",
+    "\n",
+    "import matplotlib.pyplot as plt\n",
+    "\n",
+    "plt.plot(nata_grid)"
+   ]
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.8.10"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}
diff --git a/nata/__init__.py b/nata/__init__.py
index f91efab..8cea816 100644
--- a/nata/__init__.py
+++ b/nata/__init__.py
@@ -1,6 +1,16 @@
 # -*- coding: utf-8 -*-
-# from nata.backends import *
+from nata.backends import *
+
 # from nata.comfort import load
 # from nata.comfort import activate_logging
 from nata.containers import *
 from nata.plugins import *
+
+from collections import namedtuple
+from pathlib import Path
+
+_Examples = namedtuple("Examples", ["grids", "particles"])
+examples = _Examples(
+    Path(__file__).parent / ".." / "examples" / "data" / "grids",
+    Path(__file__).parent / ".." / "examples" / "data" / "particles",
+)
diff --git a/nata/backends/osiris/hdf5.py b/nata/backends/osiris/hdf5.py
index c76dfea..56b1ae5 100644
--- a/nata/backends/osiris/hdf5.py
+++ b/nata/backends/osiris/hdf5.py
@@ -4,14 +4,15 @@
 from typing import List
 from typing import Optional
 from typing import Sequence
+from typing import Tuple
 from typing import Union
 
 import h5py as h5
 import ndindex as ndx
 import numpy as np
 
-from nata.containers import GridDataset
-from nata.containers import ParticleDataset
+from nata.containers import GridArray
+from nata.containers import ParticleArray
 from nata.types import BasicIndex
 from nata.types import BasicIndexing
 from nata.types import FileLocation
@@ -19,7 +20,7 @@
 from nata.utils.container_tools import register_backend
 
 
-@register_backend(GridDataset)
+@register_backend(GridArray)
 class Osiris_Hdf5_GridFile:
     name = "osiris_4.4.4_grid_hdf5"
     location: Optional[Path] = None
@@ -157,7 +158,7 @@ def time_unit(self):
         return self._time_unit
 
 
-@register_backend(GridDataset)
+@register_backend(GridArray)
 class Osiris_Dev_Hdf5_GridFile:
     name = "osiris_dev_grid_hdf5"
     location: Optional[Path] = None
@@ -297,7 +298,7 @@ def time_unit(self):
         return self._time_unit
 
 
-@register_backend(ParticleDataset)
+@register_backend(ParticleArray)
 class Osiris_Hdf5_ParticleFile:
     name = "osiris_4.4.4_particles_hdf5"
     location: Optional[Path] = None
@@ -308,6 +309,7 @@ def __init__(self, location: FileLocation) -> None:
         info(f"Obtaining backend props for '{self.location}'")
         with h5.File(self.location, mode="r") as fp:
             self._dataset_name = fp.attrs["NAME"].astype(str)[0]
+            self._dataset_label = fp.attrs["LABEL"].astype(str)[0]
             self._num_particles = fp["q"].shape[0] if fp["q"].shape else 0
 
             # find first all quantaties - with their names
@@ -343,6 +345,10 @@ def __init__(self, location: FileLocation) -> None:
     def dataset_name(self) -> str:
         return self._dataset_name
 
+    @property
+    def dataset_label(self) -> str:
+        return self._dataset_label
+
     @property
     def num_particles(self) -> int:
         return self._num_particles
@@ -363,6 +369,14 @@ def quantity_units(self) -> List[str]:
     def dtype(self) -> np.dtype:
         return self._dtype
 
+    @property
+    def ndim(self) -> int:
+        raise NotImplementedError
+
+    @property
+    def shape(self) -> Tuple[int, ...]:
+        raise NotImplementedError
+
     @property
     def iteration(self) -> int:
         return self._iteration
@@ -419,7 +433,7 @@ def get_data(
         return dset
 
 
-@register_backend(ParticleDataset)
+@register_backend(ParticleArray)
 class Osiris_Dev_Hdf5_ParticleFile:
     name = "osiris_dev_particles_hdf5"
     location: Optional[Path] = None
@@ -430,6 +444,7 @@ def __init__(self, location=Union[str, Path]) -> None:
         info(f"Obtaining backend props for '{self.location}'")
         with h5.File(self.location, mode="r") as fp:
             self._dataset_name = fp.attrs["NAME"].astype(str)[0]
+            self._dataset_label = fp.attrs["LABEL"].astype(str)[0]
             self._num_particles = fp["q"].shape[0] if fp["q"].shape else 0
 
             # quantaties
@@ -462,6 +477,10 @@ def __init__(self, location=Union[str, Path]) -> None:
     def dataset_name(self) -> str:
         return self._dataset_name
 
+    @property
+    def dataset_label(self) -> str:
+        return self._dataset_label
+
     @property
     def num_particles(self) -> int:
         return self._num_particles
@@ -482,6 +501,14 @@ def quantity_units(self) -> List[str]:
     def dtype(self) -> np.dtype:
         return self._dtype
 
+    @property
+    def shape(self) -> Tuple[int, ...]:
+        raise NotImplementedError
+
+    @property
+    def ndim(self) -> int:
+        raise NotImplementedError
+
     @property
     def iteration(self) -> int:
         return self._iteration
diff --git a/nata/backends/osiris/zdf.py b/nata/backends/osiris/zdf.py
index a83329d..9e95164 100644
--- a/nata/backends/osiris/zdf.py
+++ b/nata/backends/osiris/zdf.py
@@ -1,21 +1,21 @@
 # -*- coding: utf-8 -*-
 import logging
 from pathlib import Path
-from typing import List
 from typing import Optional
+from typing import Sequence
+from typing import Tuple
 from typing import Union
 
 import numpy as np
 
-from nata.containers import GridDataset
-from nata.containers import ParticleDataset
-from nata.utils.cached_property import cached_property
+from nata.containers import GridArray
+from nata.containers import ParticleArray
 from nata.utils.container_tools import register_backend
 from nata.utils.zdf import info
 from nata.utils.zdf import read
 
 
-@register_backend(GridDataset)
+@register_backend(GridArray)
 class Osiris_zdf_GridFile:
     name = "osiris_dev_grid_zdf"
     location: Optional[Path] = None
@@ -44,7 +44,7 @@ def is_valid_backend(file_path: Union[Path, str]) -> bool:
 
         return False
 
-    @cached_property
+    @property
     def _dset_name(self) -> str:
         logging.info(f"Accessing '{self.location}' for '_dset_name'")
         z_info = info(str(self.location))
@@ -56,26 +56,26 @@ def get_data(self=None, indexing=None):
         (z_data, z_info) = read(str(self.location))
         return z_data.transpose()
 
-    @cached_property
+    @property
     def dataset_name(self) -> str:
         logging.info(f"Accessing '{self.location}' for 'dataset_name'")
         z_info = info(str(self.location))
         label = z_info.grid.label
         return z_info.grid.name or self.clean(label)
 
-    @cached_property
+    @property
     def dataset_label(self) -> str:
         logging.info(f"Accessing '{self.location}' for 'dataset_label'")
         z_info = info(str(self.location))
         return z_info.grid.label
 
-    @cached_property
+    @property
     def ndim(self):
         logging.info(f"Accessing '{self.location}' for 'ndim'")
         z_info = info(str(self.location))
         return z_info.grid.ndims
 
-    @cached_property
+    @property
     def shape(self):
         logging.info(f"Accessing '{self.location}' for 'shape'")
         z_info = info(str(self.location))
@@ -84,19 +84,19 @@ def shape(self):
             nx.append(n.item())
         return tuple(nx)
 
-    @cached_property
+    @property
     def dtype(self):
         logging.info(f"Accessing '{self.location}' for 'dtype'")
         (z_data, z_info) = read(str(self.location))
         return z_data.dtype
 
-    @cached_property
+    @property
     def dataset_unit(self):
         logging.info(f"Accessing '{self.location}' for 'dataset_unit'")
         z_info = info(str(self.location))
         return z_info.grid.units
 
-    @cached_property
+    @property
     def axes_min(self):
         logging.info(f"Accessing '{self.location}' for 'axes_min'")
         min_values = []
@@ -105,7 +105,7 @@ def axes_min(self):
             min_values.append(axis.min)
         return np.array(min_values)
 
-    @cached_property
+    @property
     def axes_max(self):
         logging.info(f"Accessing '{self.location}' for 'axes_max'")
         max_values = []
@@ -114,7 +114,7 @@ def axes_max(self):
             max_values.append(axis.max)
         return np.array(max_values)
 
-    @cached_property
+    @property
     def axes_names(self):
         logging.info(f"Accessing '{self.location}' for 'axes_names'")
         names = []
@@ -124,7 +124,7 @@ def axes_names(self):
             names.append(axis.name or self.clean(label))
         return np.array(names)
 
-    @cached_property
+    @property
     def axes_labels(self):
         logging.info(f"Accessing '{self.location}' for 'axes_labels'")
         long_names = []
@@ -133,7 +133,7 @@ def axes_labels(self):
             long_names.append(axis.label)
         return np.array(long_names)
 
-    @cached_property
+    @property
     def axes_units(self):
         logging.info(f"Accessing '{self.location}' for 'axes_units'")
         units = []
@@ -142,19 +142,19 @@ def axes_units(self):
             units.append(axis.units)
         return np.array(units)
 
-    @cached_property
+    @property
     def iteration(self):
         logging.info(f"Accessing '{self.location}' for 'iteration'")
         z_info = info(str(self.location))
         return z_info.iteration.n
 
-    @cached_property
+    @property
     def time_step(self):
         logging.info(f"Accessing '{self.location}' for 'time_step'")
         z_info = info(str(self.location))
         return z_info.iteration.t
 
-    @cached_property
+    @property
     def time_unit(self):
         logging.info(f"Accessing '{self.location}' for 'time_unit'")
         z_info = info(str(self.location))
@@ -172,12 +172,12 @@ def clean(self, name):
         )
 
 
-@register_backend(ParticleDataset)
+@register_backend(ParticleArray)
 class Osiris_zdf_ParticleFile:
     name = "osiris_dev_particles_zdf"
     location: Optional[Path] = None
 
-    def __init__(self, location=Union[str, Path]) -> None:
+    def __init__(self, location: Union[str, Path]) -> None:
         self.location = location if isinstance(location, Path) else Path(location)
 
     @staticmethod
@@ -195,13 +195,19 @@ def is_valid_backend(file_path: Path) -> bool:
 
         return False
 
-    @cached_property
+    @property
     def dataset_name(self) -> str:
         logging.info(f"Accessing '{self.location}' for 'dataset_name'")
         z_info = info(str(self.location))
         return z_info.particles.name
 
-    @cached_property
+    @property
+    def dataset_label(self) -> str:
+        logging.info(f"Accessing '{self.location}' for 'dataset_label'")
+        z_info = info(str(self.location))
+        return z_info.particles.label
+
+    @property
     def num_particles(self) -> int:
         logging.info(f"Accessing '{self.location}' for 'num_particles'")
         z_info = info(str(self.location))
@@ -225,8 +231,8 @@ def get_data(self, indexing=None, fields=None) -> np.ndarray:
 
         return dset
 
-    @cached_property
-    def quantity_names(self) -> List[str]:
+    @property
+    def quantity_names(self) -> Sequence[str]:
         logging.info(f"Accessing '{self.location}' for 'quantity_names'")
         z_info = info(str(self.location))
         quantities = []
@@ -237,8 +243,8 @@ def quantity_names(self) -> List[str]:
 
         return quantities
 
-    @cached_property
-    def quantity_labels(self) -> List[str]:
+    @property
+    def quantity_labels(self) -> Sequence[str]:
         logging.info(f"Accessing '{self.location}' for 'quantity_labels'")
         z_info = info(str(self.location))
         names = []
@@ -246,8 +252,8 @@ def quantity_labels(self) -> List[str]:
             names.append(z_info.particles.qlabels[quant])
         return names
 
-    @cached_property
-    def quantity_units(self) -> List[str]:
+    @property
+    def quantity_units(self) -> Sequence[str]:
         logging.info(f"Accessing '{self.location}' for 'quantity_units'")
         z_info = info(str(self.location))
         units = []
@@ -256,7 +262,7 @@ def quantity_units(self) -> List[str]:
 
         return units
 
-    @cached_property
+    @property
     def dtype(self) -> np.dtype:
         logging.info(f"Accessing '{self.location}' for 'dtype'")
         (z_data, z_info) = read(str(self.location))
@@ -266,19 +272,27 @@ def dtype(self) -> np.dtype:
 
         return np.dtype(fields)
 
-    @cached_property
+    @property
+    def ndim(self) -> int:
+        raise NotImplementedError
+
+    @property
+    def shape(self) -> Tuple[int, ...]:
+        raise NotImplementedError
+
+    @property
     def iteration(self) -> int:
         logging.info(f"Accessing '{self.location}' for 'iteration'")
         z_info = info(str(self.location))
         return z_info.iteration.n
 
-    @cached_property
+    @property
     def time_step(self) -> float:
         logging.info(f"Accessing '{self.location}' for 'time_step'")
         z_info = info(str(self.location))
         return z_info.iteration.t
 
-    @cached_property
+    @property
     def time_unit(self) -> str:
         logging.info(f"Accessing '{self.location}' for 'time_unit'")
         z_info = info(str(self.location))
diff --git a/nata/containers/grid.py b/nata/containers/grid.py
index 1dea103..90eb040 100644
--- a/nata/containers/grid.py
+++ b/nata/containers/grid.py
@@ -235,16 +235,13 @@ def from_array(
                 tmp = []
                 for i, ax in enumerate(axes):
                     if not isinstance(ax, Axis):
-                        ax = Axis.from_array(da.asanyarray(ax), name=f"axis{i}")
+                        ax = Axis.from_array(ax, name=f"axis{i}")
                     tmp.append(ax)
 
                 axes = tuple(tmp)
 
-        if time is None:
-            time = Axis.from_array(0.0, name="time", label="time")
-        else:
-            if not isinstance(time, Axis):
-                time = Axis.from_array(time, name="time", label="time")
+        if not isinstance(time, Axis):
+            time = Axis.from_array(time, name="time", label="time")
 
         return cls(data, axes, time, name, label, unit)
 
diff --git a/nata/containers/utils.py b/nata/containers/utils.py
index 768c92f..d770208 100644
--- a/nata/containers/utils.py
+++ b/nata/containers/utils.py
@@ -11,6 +11,8 @@
 from nata.types import BackendType
 from nata.types import DatasetType
 
+from .core import HasNumpyInterface
+
 
 def is_unique(iterable: Iterable) -> bool:
     return len(set(iterable)) == 1
@@ -41,3 +43,17 @@ def unstructured_to_structured(data: da.Array, new_dtype: np.dtype) -> da.Array:
     new_shape = data.shape[:-1]
     new_data = delayed(recfunctions.unstructured_to_structured)(data, dtype=new_dtype)
     return da.from_delayed(new_data, new_shape, dtype=new_dtype)
+
+
+def to_numpy(array_like: HasNumpyInterface) -> np.ndarray:
+    if isinstance(array_like, HasNumpyInterface):
+        return array_like.to_numpy()
+    else:
+        raise TypeError(f"requires object of type '{HasNumpyInterface}'")
+
+
+def to_dask(array_like: HasNumpyInterface) -> da.Array:
+    if isinstance(array_like, HasNumpyInterface):
+        return array_like.to_dask()
+    else:
+        raise TypeError(f"requires object of type '{HasNumpyInterface}'")
diff --git a/nata/utils/container_tools.py b/nata/utils/container_tools.py
index e70610f..6f96eb5 100644
--- a/nata/utils/container_tools.py
+++ b/nata/utils/container_tools.py
@@ -16,7 +16,7 @@ def add_backend_to_container(backend: BackendType):
             backend.__getitem__ = backend.get_data
         else:
             warn(
-                f"{backend} is an invalid backend for '{container}'. "
+                f"Invalid backend '{backend.__name__}' for '{container.__name__}'. "
                 + "Skipping backend registration!"
             )
         return backend
diff --git a/poetry.lock b/poetry.lock
index 5a90edf..b3154ee 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -8,7 +8,7 @@ python-versions = "*"
 
 [[package]]
 name = "anyio"
-version = "2.2.0"
+version = "3.0.1"
 description = "High level compatibility layer for multiple asynchronous event loop implementations"
 category = "main"
 optional = true
@@ -19,7 +19,6 @@ idna = ">=2.8"
 sniffio = ">=1.1"
 
 [package.extras]
-curio = ["curio (>=1.4)"]
 doc = ["sphinx-rtd-theme", "sphinx-autodoc-typehints (>=1.2.0)"]
 test = ["coverage[toml] (>=4.5)", "hypothesis (>=4.0)", "pytest (>=6.0)", "trustme", "uvloop (<0.15)", "uvloop (>=0.15)"]
 trio = ["trio (>=0.16)"]
@@ -67,21 +66,21 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
 
 [[package]]
 name = "attrs"
-version = "20.3.0"
+version = "21.2.0"
 description = "Classes Without Boilerplate"
 category = "main"
 optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
 
 [package.extras]
-dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface", "furo", "sphinx", "pre-commit"]
-docs = ["furo", "sphinx", "zope.interface"]
-tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface"]
-tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six"]
+dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "furo", "sphinx", "sphinx-notfound-page", "pre-commit"]
+docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"]
+tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface"]
+tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins"]
 
 [[package]]
 name = "babel"
-version = "2.9.0"
+version = "2.9.1"
 description = "Internationalization utilities"
 category = "main"
 optional = true
@@ -111,6 +110,14 @@ packaging = "*"
 six = ">=1.9.0"
 webencodings = "*"
 
+[[package]]
+name = "certifi"
+version = "2020.12.5"
+description = "Python package for providing Mozilla's CA Bundle."
+category = "main"
+optional = true
+python-versions = "*"
+
 [[package]]
 name = "cffi"
 version = "1.14.5"
@@ -122,6 +129,14 @@ python-versions = "*"
 [package.dependencies]
 pycparser = "*"
 
+[[package]]
+name = "chardet"
+version = "4.0.0"
+description = "Universal encoding detector for Python 2 and 3"
+category = "main"
+optional = true
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
+
 [[package]]
 name = "colorama"
 version = "0.4.4"
@@ -176,7 +191,7 @@ distributed = ["distributed (>=2.0)"]
 
 [[package]]
 name = "decorator"
-version = "5.0.6"
+version = "5.0.7"
 description = "Decorators for Humans"
 category = "main"
 optional = true
@@ -190,20 +205,9 @@ category = "main"
 optional = true
 python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
 
-[[package]]
-name = "deprecation"
-version = "2.1.0"
-description = "A library to handle automated deprecations"
-category = "main"
-optional = true
-python-versions = "*"
-
-[package.dependencies]
-packaging = "*"
-
 [[package]]
 name = "docutils"
-version = "0.17"
+version = "0.17.1"
 description = "Docutils -- Python Documentation Utilities"
 category = "dev"
 optional = true
@@ -261,11 +265,11 @@ zoneinfo = ["importlib-resources (>=3.3.0)", "backports.zoneinfo (>=0.2.1)", "tz
 
 [[package]]
 name = "idna"
-version = "3.1"
+version = "2.10"
 description = "Internationalized Domain Names in Applications (IDNA)"
 category = "main"
 optional = true
-python-versions = ">=3.4"
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
 
 [[package]]
 name = "imagesize"
@@ -285,7 +289,7 @@ python-versions = "*"
 
 [[package]]
 name = "ipykernel"
-version = "5.5.3"
+version = "5.5.5"
 description = "IPython Kernel for Jupyter"
 category = "main"
 optional = true
@@ -303,7 +307,7 @@ test = ["pytest (!=5.3.4)", "pytest-cov", "flaky", "nose", "jedi (<=0.17.2)"]
 
 [[package]]
 name = "ipython"
-version = "7.22.0"
+version = "7.23.1"
 description = "IPython: Productive Interactive Computing"
 category = "main"
 optional = true
@@ -315,6 +319,7 @@ backcall = "*"
 colorama = {version = "*", markers = "sys_platform == \"win32\""}
 decorator = "*"
 jedi = ">=0.16"
+matplotlib-inline = "*"
 pexpect = {version = ">4.3", markers = "sys_platform != \"win32\""}
 pickleshare = "*"
 prompt-toolkit = ">=2.0.0,<3.0.0 || >3.0.0,<3.0.1 || >3.0.1,<3.1.0"
@@ -376,17 +381,17 @@ testing = ["Django (<3.1)", "colorama", "docopt", "pytest (<6.0.0)"]
 
 [[package]]
 name = "jinja2"
-version = "2.11.3"
+version = "3.0.0"
 description = "A very fast and expressive template engine."
 category = "main"
 optional = true
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
+python-versions = ">=3.6"
 
 [package.dependencies]
-MarkupSafe = ">=0.23"
+MarkupSafe = ">=2.0.0rc2"
 
 [package.extras]
-i18n = ["Babel (>=0.8)"]
+i18n = ["Babel (>=2.7)"]
 
 [[package]]
 name = "json5"
@@ -482,63 +487,46 @@ python-versions = ">=3.6"
 pywin32 = {version = ">=1.0", markers = "sys_platform == \"win32\""}
 traitlets = "*"
 
-[[package]]
-name = "jupyter-packaging"
-version = "0.8.3"
-description = "Jupyter Packaging Utilities."
-category = "main"
-optional = true
-python-versions = ">=3.6"
-
-[package.dependencies]
-deprecation = "*"
-packaging = "*"
-tomlkit = "*"
-
-[package.extras]
-test = ["build", "coverage", "pytest", "pytest-cov", "pytest-mock"]
-
 [[package]]
 name = "jupyter-server"
-version = "1.6.0"
+version = "1.7.0"
 description = "The backend—i.e. core services, APIs, and REST endpoints—to Jupyter web applications."
 category = "main"
 optional = true
 python-versions = ">=3.6"
 
 [package.dependencies]
-anyio = ">=2.0.2"
+anyio = {version = ">=3.0.1,<4", markers = "python_version >= \"3.7\""}
 argon2-cffi = "*"
 ipython-genutils = "*"
 jinja2 = "*"
 jupyter-client = ">=6.1.1"
-jupyter-core = ">=4.4.0"
+jupyter-core = ">=4.6.0"
 nbconvert = "*"
 nbformat = "*"
 prometheus-client = "*"
-pywin32 = {version = ">=1.0", markers = "sys_platform == \"win32\""}
 pyzmq = ">=17"
 Send2Trash = "*"
 terminado = ">=0.8.3"
 tornado = ">=6.1.0"
 traitlets = ">=4.2.1"
+websocket-client = "*"
 
 [package.extras]
-test = ["coverage", "requests", "pytest", "pytest-cov", "pytest-tornasync", "pytest-console-scripts", "ipykernel"]
+test = ["coverage", "pytest", "pytest-cov", "pytest-mock", "requests", "pytest-tornasync", "pytest-console-scripts", "ipykernel"]
 
 [[package]]
 name = "jupyterlab"
-version = "3.0.14"
-description = "The JupyterLab server extension."
+version = "3.0.15"
+description = "JupyterLab computational environment"
 category = "main"
 optional = true
 python-versions = ">=3.6"
 
 [package.dependencies]
 ipython = "*"
-jinja2 = ">=2.10"
+jinja2 = ">=2.1"
 jupyter-core = "*"
-jupyter-packaging = ">=0.7,<1.0"
 jupyter-server = ">=1.4,<2.0"
 jupyterlab-server = ">=2.3,<3.0"
 nbclassic = ">=0.2,<1.0"
@@ -546,8 +534,7 @@ packaging = "*"
 tornado = ">=6.1.0"
 
 [package.extras]
-docs = ["jsx-lexer", "recommonmark", "sphinx", "sphinx-rtd-theme", "sphinx-copybutton"]
-test = ["pytest (>=6.0)", "pytest-cov", "pytest-console-scripts", "pytest-check-links", "jupyterlab-server[test] (>=2.0,<3.0)", "requests", "wheel", "virtualenv", "nose-exclude"]
+test = ["coverage", "pytest (>=6.0)", "pytest-cov", "pytest-console-scripts", "pytest-check-links (>=0.5)", "jupyterlab-server[test] (>=2.2,<3.0)", "requests", "requests-cache", "virtualenv", "check-manifest"]
 
 [[package]]
 name = "jupyterlab-pygments"
@@ -562,8 +549,8 @@ pygments = ">=2.4.1,<3"
 
 [[package]]
 name = "jupyterlab-server"
-version = "2.4.0"
-description = "JupyterLab Server"
+version = "2.5.1"
+description = "A set of server components for JupyterLab and JupyterLab like applications ."
 category = "main"
 optional = true
 python-versions = ">=3.6"
@@ -578,7 +565,7 @@ packaging = "*"
 requests = "*"
 
 [package.extras]
-test = ["codecov", "ipykernel", "pytest (>=5.3.2)", "pytest-cov", "jupyter-server", "pytest-console-scripts", "strict-rfc3339", "wheel"]
+test = ["codecov", "ipykernel", "pytest (>=5.3.2)", "pytest-cov", "jupyter-server", "openapi-core (>=0.13.8,<0.14.0)", "pytest-console-scripts", "strict-rfc3339", "ruamel.yaml", "wheel"]
 
 [[package]]
 name = "jupyterlab-widgets"
@@ -598,15 +585,15 @@ python-versions = ">=3.6"
 
 [[package]]
 name = "markupsafe"
-version = "1.1.1"
+version = "2.0.0"
 description = "Safely add untrusted strings to HTML/XML markup."
 category = "main"
 optional = true
-python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*"
+python-versions = ">=3.6"
 
 [[package]]
 name = "matplotlib"
-version = "3.4.1"
+version = "3.4.2"
 description = "Python plotting package"
 category = "main"
 optional = false
@@ -620,6 +607,17 @@ pillow = ">=6.2.0"
 pyparsing = ">=2.2.1"
 python-dateutil = ">=2.7"
 
+[[package]]
+name = "matplotlib-inline"
+version = "0.1.2"
+description = "Inline Matplotlib backend for Jupyter"
+category = "main"
+optional = true
+python-versions = ">=3.5"
+
+[package.dependencies]
+traitlets = "*"
+
 [[package]]
 name = "mistune"
 version = "0.8.4"
@@ -642,7 +640,7 @@ tests = ["pytest (>=4.6)"]
 
 [[package]]
 name = "nbclassic"
-version = "0.2.7"
+version = "0.2.8"
 description = "Jupyter Notebook as a Jupyter Server Extension."
 category = "main"
 optional = true
@@ -774,7 +772,7 @@ test = ["pytest", "coverage", "requests", "nbval", "selenium", "pytest-cov", "re
 
 [[package]]
 name = "numpy"
-version = "1.20.2"
+version = "1.20.3"
 description = "NumPy is the fundamental package for array computing with Python."
 category = "main"
 optional = false
@@ -897,7 +895,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
 
 [[package]]
 name = "pygments"
-version = "2.8.1"
+version = "2.9.0"
 description = "Pygments is a syntax highlighting package written in Python."
 category = "main"
 optional = true
@@ -921,7 +919,7 @@ python-versions = ">=3.5"
 
 [[package]]
 name = "pytest"
-version = "6.2.3"
+version = "6.2.4"
 description = "pytest: simple powerful testing with Python"
 category = "dev"
 optional = false
@@ -997,7 +995,7 @@ py = {version = "*", markers = "implementation_name == \"pypy\""}
 
 [[package]]
 name = "qtconsole"
-version = "5.0.3"
+version = "5.1.0"
 description = "Jupyter Qt console"
 category = "main"
 optional = true
@@ -1040,14 +1038,20 @@ sphinx = ">=1.3.1"
 
 [[package]]
 name = "requests"
-version = "2.15.1"
+version = "2.25.1"
 description = "Python HTTP for Humans."
 category = "main"
 optional = true
-python-versions = "*"
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
+
+[package.dependencies]
+certifi = ">=2017.4.17"
+chardet = ">=3.0.2,<5"
+idna = ">=2.5,<3"
+urllib3 = ">=1.21.1,<1.27"
 
 [package.extras]
-security = ["cryptography (>=1.3.4)", "idna (>=2.0.0)", "pyOpenSSL (>=0.14)"]
+security = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)"]
 socks = ["PySocks (>=1.5.6,!=1.5.7)", "win-inet-pton"]
 
 [[package]]
@@ -1060,7 +1064,7 @@ python-versions = "*"
 
 [[package]]
 name = "six"
-version = "1.15.0"
+version = "1.16.0"
 description = "Python 2 and 3 compatibility utilities"
 category = "main"
 optional = false
@@ -1121,17 +1125,6 @@ docs = ["sphinxcontrib-websupport"]
 lint = ["flake8 (>=3.5.0)", "isort", "mypy (>=0.800)", "docutils-stubs"]
 test = ["pytest", "pytest-cov", "html5lib", "cython", "typed-ast"]
 
-[[package]]
-name = "sphinx-rtd-theme"
-version = "0.4.3"
-description = "Read the Docs theme for Sphinx"
-category = "dev"
-optional = true
-python-versions = "*"
-
-[package.dependencies]
-sphinx = "*"
-
 [[package]]
 name = "sphinxcontrib-applehelp"
 version = "1.0.2"
@@ -1216,7 +1209,7 @@ mpmath = ">=0.19"
 
 [[package]]
 name = "terminado"
-version = "0.9.4"
+version = "0.9.5"
 description = "Tornado websocket backend for the Xterm.js Javascript terminal emulator library."
 category = "main"
 optional = true
@@ -1224,7 +1217,7 @@ python-versions = ">=3.6"
 
 [package.dependencies]
 ptyprocess = {version = "*", markers = "os_name != \"nt\""}
-pywinpty = {version = ">=0.5", markers = "os_name == \"nt\""}
+pywinpty = {version = ">=0.5,<1", markers = "os_name == \"nt\""}
 tornado = ">=4"
 
 [package.extras]
@@ -1249,14 +1242,6 @@ category = "dev"
 optional = false
 python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
 
-[[package]]
-name = "tomlkit"
-version = "0.7.0"
-description = "Style preserving TOML library"
-category = "main"
-optional = true
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
-
 [[package]]
 name = "toolz"
 version = "0.11.1"
@@ -1287,6 +1272,19 @@ ipython-genutils = "*"
 [package.extras]
 test = ["pytest"]
 
+[[package]]
+name = "urllib3"
+version = "1.26.4"
+description = "HTTP library with thread-safe connection pooling, file post, and more."
+category = "main"
+optional = true
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4"
+
+[package.extras]
+secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"]
+socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"]
+brotli = ["brotlipy (>=0.6.0)"]
+
 [[package]]
 name = "wcwidth"
 version = "0.2.5"
@@ -1303,6 +1301,17 @@ category = "main"
 optional = true
 python-versions = "*"
 
+[[package]]
+name = "websocket-client"
+version = "0.59.0"
+description = "WebSocket client for Python with low level API options"
+category = "main"
+optional = true
+python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
+
+[package.dependencies]
+six = "*"
+
 [[package]]
 name = "widgetsnbextension"
 version = "3.5.1"
@@ -1321,7 +1330,7 @@ jupyter = ["jupyterlab", "ipywidgets", "jupyter"]
 [metadata]
 lock-version = "1.1"
 python-versions = "^3.8"
-content-hash = "68050364bf1ae0e9e8ef0629d2868c8100e0edb3bc42afc0a28cf9470ebe66a5"
+content-hash = "ab2fd3eb5e93091b789e14f15dea0d41d81d4d0b0f26ca91bf42eae3fcd69d59"
 
 [metadata.files]
 alabaster = [
@@ -1329,8 +1338,8 @@ alabaster = [
     {file = "alabaster-0.7.12.tar.gz", hash = "sha256:a661d72d58e6ea8a57f7a86e37d86716863ee5e92788398526d58b26a4e4dc02"},
 ]
 anyio = [
-    {file = "anyio-2.2.0-py3-none-any.whl", hash = "sha256:aa3da546ed17f097ca876c78024dea380a3b7fa80759abfdda59f12176a3dac8"},
-    {file = "anyio-2.2.0.tar.gz", hash = "sha256:4a41c5b3a65ed92e469d51b6fba3779301850ea2e352afcf9e36c46f21ee14a9"},
+    {file = "anyio-3.0.1-py3-none-any.whl", hash = "sha256:ed71f7542ef39875b65def219794d9dcb0a48c571317b13612c12b1f292701b5"},
+    {file = "anyio-3.0.1.tar.gz", hash = "sha256:1ef7622396ab55829d4236a6f75e2199df6d26a4ba79bea0cb942a5fd2f79a23"},
 ]
 appnope = [
     {file = "appnope-0.1.2-py2.py3-none-any.whl", hash = "sha256:93aa393e9d6c54c5cd570ccadd8edad61ea0c4b9ea7a01409020c9aa019eb442"},
@@ -1365,12 +1374,12 @@ atomicwrites = [
     {file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"},
 ]
 attrs = [
-    {file = "attrs-20.3.0-py2.py3-none-any.whl", hash = "sha256:31b2eced602aa8423c2aea9c76a724617ed67cf9513173fd3a4f03e3a929c7e6"},
-    {file = "attrs-20.3.0.tar.gz", hash = "sha256:832aa3cde19744e49938b91fea06d69ecb9e649c93ba974535d08ad92164f700"},
+    {file = "attrs-21.2.0-py2.py3-none-any.whl", hash = "sha256:149e90d6d8ac20db7a955ad60cf0e6881a3f20d37096140088356da6c716b0b1"},
+    {file = "attrs-21.2.0.tar.gz", hash = "sha256:ef6aaac3ca6cd92904cdd0d83f629a15f18053ec84e6432106f7a4d04ae4f5fb"},
 ]
 babel = [
-    {file = "Babel-2.9.0-py2.py3-none-any.whl", hash = "sha256:9d35c22fcc79893c3ecc85ac4a56cde1ecf3f19c540bba0922308a6c06ca6fa5"},
-    {file = "Babel-2.9.0.tar.gz", hash = "sha256:da031ab54472314f210b0adcff1588ee5d1d1d0ba4dbd07b94dba82bde791e05"},
+    {file = "Babel-2.9.1-py2.py3-none-any.whl", hash = "sha256:ab49e12b91d937cd11f0b67cb259a57ab4ad2b59ac7a3b41d6c06c0ac5b0def9"},
+    {file = "Babel-2.9.1.tar.gz", hash = "sha256:bc0c176f9f6a994582230df350aa6e05ba2ebe4b3ac317eab29d9be5d2768da0"},
 ]
 backcall = [
     {file = "backcall-0.2.0-py2.py3-none-any.whl", hash = "sha256:fbbce6a29f263178a1f7915c1940bde0ec2b2a967566fe1c65c1dfb7422bd255"},
@@ -1380,6 +1389,10 @@ bleach = [
     {file = "bleach-3.3.0-py2.py3-none-any.whl", hash = "sha256:6123ddc1052673e52bab52cdc955bcb57a015264a1c57d37bea2f6b817af0125"},
     {file = "bleach-3.3.0.tar.gz", hash = "sha256:98b3170739e5e83dd9dc19633f074727ad848cbedb6026708c8ac2d3b697a433"},
 ]
+certifi = [
+    {file = "certifi-2020.12.5-py2.py3-none-any.whl", hash = "sha256:719a74fb9e33b9bd44cc7f3a8d94bc35e4049deebe19ba7d8e108280cfd59830"},
+    {file = "certifi-2020.12.5.tar.gz", hash = "sha256:1a4995114262bffbc2413b159f2a1a480c969de6e6eb13ee966d470af86af59c"},
+]
 cffi = [
     {file = "cffi-1.14.5-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:bb89f306e5da99f4d922728ddcd6f7fcebb3241fc40edebcb7284d7514741991"},
     {file = "cffi-1.14.5-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:34eff4b97f3d982fb93e2831e6750127d1355a923ebaeeb565407b3d2f8d41a1"},
@@ -1419,6 +1432,10 @@ cffi = [
     {file = "cffi-1.14.5-cp39-cp39-win_amd64.whl", hash = "sha256:f2d45f97ab6bb54753eab54fffe75aaf3de4ff2341c9daee1987ee1837636f1d"},
     {file = "cffi-1.14.5.tar.gz", hash = "sha256:fd78e5fee591709f32ef6edb9a015b4aa1a5022598e36227500c8f4e02328d9c"},
 ]
+chardet = [
+    {file = "chardet-4.0.0-py2.py3-none-any.whl", hash = "sha256:f864054d66fd9118f2e67044ac8981a54775ec5b67aed0441892edb553d21da5"},
+    {file = "chardet-4.0.0.tar.gz", hash = "sha256:0d6f53a15db4120f2b08c94f11e7d93d2c911ee118b6b30a04ec3ee8310179fa"},
+]
 colorama = [
     {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"},
     {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"},
@@ -1436,20 +1453,16 @@ dask = [
     {file = "dask-2.30.0.tar.gz", hash = "sha256:a1669022e25de99b227c3d83da4801f032415962dac431099bf0534648e41a54"},
 ]
 decorator = [
-    {file = "decorator-5.0.6-py3-none-any.whl", hash = "sha256:d9f2d2863183a3c0df05f4b786f2e6b8752c093b3547a558f287bf3022fd2bf4"},
-    {file = "decorator-5.0.6.tar.gz", hash = "sha256:f2e71efb39412bfd23d878e896a51b07744f2e2250b2e87d158e76828c5ae202"},
+    {file = "decorator-5.0.7-py3-none-any.whl", hash = "sha256:945d84890bb20cc4a2f4a31fc4311c0c473af65ea318617f13a7257c9a58bc98"},
+    {file = "decorator-5.0.7.tar.gz", hash = "sha256:6f201a6c4dac3d187352661f508b9364ec8091217442c9478f1f83c003a0f060"},
 ]
 defusedxml = [
     {file = "defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61"},
     {file = "defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69"},
 ]
-deprecation = [
-    {file = "deprecation-2.1.0-py2.py3-none-any.whl", hash = "sha256:a10811591210e1fb0e768a8c25517cabeabcba6f0bf96564f8ff45189f90b14a"},
-    {file = "deprecation-2.1.0.tar.gz", hash = "sha256:72b3bde64e5d778694b0cf68178aed03d15e15477116add3fb773e581f9518ff"},
-]
 docutils = [
-    {file = "docutils-0.17-py2.py3-none-any.whl", hash = "sha256:a71042bb7207c03d5647f280427f14bfbd1a65c9eb84f4b341d85fafb6bb4bdf"},
-    {file = "docutils-0.17.tar.gz", hash = "sha256:e2ffeea817964356ba4470efba7c2f42b6b0de0b04e66378507e3e2504bbff4c"},
+    {file = "docutils-0.17.1-py2.py3-none-any.whl", hash = "sha256:cf316c8370a737a022b72b56874f6602acf974a37a9fba42ec2876387549fc61"},
+    {file = "docutils-0.17.1.tar.gz", hash = "sha256:686577d2e4c32380bb50cbb22f575ed742d58168cee37e99117a854bcd88f125"},
 ]
 entrypoints = [
     {file = "entrypoints-0.3-py2.py3-none-any.whl", hash = "sha256:589f874b313739ad35be6e0cd7efde2a4e9b6fea91edcc34e58ecbb8dbe56d19"},
@@ -1472,8 +1485,8 @@ hypothesis = [
     {file = "hypothesis-5.49.0.tar.gz", hash = "sha256:36a4d5587c34193125d654b61bf9284e24a227d1edd339c49143378658a10c7d"},
 ]
 idna = [
-    {file = "idna-3.1-py3-none-any.whl", hash = "sha256:5205d03e7bcbb919cc9c19885f9920d622ca52448306f2377daede5cf3faac16"},
-    {file = "idna-3.1.tar.gz", hash = "sha256:c5b02147e01ea9920e6b0a3f1f7bb833612d507592c837a6c49552768f4054e1"},
+    {file = "idna-2.10-py2.py3-none-any.whl", hash = "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0"},
+    {file = "idna-2.10.tar.gz", hash = "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6"},
 ]
 imagesize = [
     {file = "imagesize-1.2.0-py2.py3-none-any.whl", hash = "sha256:6965f19a6a2039c7d48bca7dba2473069ff854c36ae6f19d2cde309d998228a1"},
@@ -1484,12 +1497,12 @@ iniconfig = [
     {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"},
 ]
 ipykernel = [
-    {file = "ipykernel-5.5.3-py3-none-any.whl", hash = "sha256:21abd584543759e49010975a4621603b3cf871b1039cb3879a14094717692614"},
-    {file = "ipykernel-5.5.3.tar.gz", hash = "sha256:a682e4f7affd86d9ce9b699d21bcab6d5ec9fbb2bfcb194f2706973b252bc509"},
+    {file = "ipykernel-5.5.5-py3-none-any.whl", hash = "sha256:29eee66548ee7c2edb7941de60c0ccf0a7a8dd957341db0a49c5e8e6a0fcb712"},
+    {file = "ipykernel-5.5.5.tar.gz", hash = "sha256:e976751336b51082a89fc2099fb7f96ef20f535837c398df6eab1283c2070884"},
 ]
 ipython = [
-    {file = "ipython-7.22.0-py3-none-any.whl", hash = "sha256:c0ce02dfaa5f854809ab7413c601c4543846d9da81010258ecdab299b542d199"},
-    {file = "ipython-7.22.0.tar.gz", hash = "sha256:9c900332d4c5a6de534b4befeeb7de44ad0cc42e8327fa41b7685abde58cec74"},
+    {file = "ipython-7.23.1-py3-none-any.whl", hash = "sha256:f78c6a3972dde1cc9e4041cbf4de583546314ba52d3c97208e5b6b2221a9cb7d"},
+    {file = "ipython-7.23.1.tar.gz", hash = "sha256:714810a5c74f512b69d5f3b944c86e592cee0a5fb9c728e582f074610f6cf038"},
 ]
 ipython-genutils = [
     {file = "ipython_genutils-0.2.0-py2.py3-none-any.whl", hash = "sha256:72dd37233799e619666c9f639a9da83c34013a73e8bbc79a7a6348d93c61fab8"},
@@ -1504,8 +1517,8 @@ jedi = [
     {file = "jedi-0.18.0.tar.gz", hash = "sha256:92550a404bad8afed881a137ec9a461fed49eca661414be45059329614ed0707"},
 ]
 jinja2 = [
-    {file = "Jinja2-2.11.3-py2.py3-none-any.whl", hash = "sha256:03e47ad063331dd6a3f04a43eddca8a966a26ba0c5b7207a9a9e4e08f1b29419"},
-    {file = "Jinja2-2.11.3.tar.gz", hash = "sha256:a6d58433de0ae800347cab1fa3043cebbabe8baa9d29e668f1c768cb87a333c6"},
+    {file = "Jinja2-3.0.0-py3-none-any.whl", hash = "sha256:2f2de5285cf37f33d33ecd4a9080b75c87cd0c1994d5a9c6df17131ea1f049c6"},
+    {file = "Jinja2-3.0.0.tar.gz", hash = "sha256:ea8d7dd814ce9df6de6a761ec7f1cac98afe305b8cdc4aaae4e114b8d8ce24c5"},
 ]
 json5 = [
     {file = "json5-0.9.5-py2.py3-none-any.whl", hash = "sha256:af1a1b9a2850c7f62c23fde18be4749b3599fd302f494eebf957e2ada6b9e42c"},
@@ -1532,25 +1545,21 @@ jupyter-core = [
     {file = "jupyter_core-4.7.1-py3-none-any.whl", hash = "sha256:8c6c0cac5c1b563622ad49321d5ec47017bd18b94facb381c6973a0486395f8e"},
     {file = "jupyter_core-4.7.1.tar.gz", hash = "sha256:79025cb3225efcd36847d0840f3fc672c0abd7afd0de83ba8a1d3837619122b4"},
 ]
-jupyter-packaging = [
-    {file = "jupyter_packaging-0.8.3-py2.py3-none-any.whl", hash = "sha256:67b37ea81c37d12aefe1057c99b3e3121f5c6a49605249f45a302c3b45d94c1f"},
-    {file = "jupyter_packaging-0.8.3.tar.gz", hash = "sha256:c52debebf8b23e5903ef22053294885440b77c525b1035afa7268585fc1a83a7"},
-]
 jupyter-server = [
-    {file = "jupyter_server-1.6.0-py3-none-any.whl", hash = "sha256:b0ae09aeaf4a73d4f195d55ade9bfdc2e399276c158e27ce820796d2e10ba1f5"},
-    {file = "jupyter_server-1.6.0.tar.gz", hash = "sha256:348f2c744d1fa1676d314475e0be357a95b21cbe6e19d15c2a25a9ea647f99d2"},
+    {file = "jupyter_server-1.7.0-py3-none-any.whl", hash = "sha256:f7c0d2583d943c25f9893c91c9315b270582c249e2e08ef78fed9a438aa7a375"},
+    {file = "jupyter_server-1.7.0.tar.gz", hash = "sha256:d9cfc1d21ff9951f185d9cbf9b742b911f57b98887ed79e210acd6f720505576"},
 ]
 jupyterlab = [
-    {file = "jupyterlab-3.0.14-py3-none-any.whl", hash = "sha256:223ad786032119f495edc894a81925b6cc327a184f150adbc4e5ef94965d4921"},
-    {file = "jupyterlab-3.0.14.tar.gz", hash = "sha256:713a84991dfcca8c0bc260911f1bd54ac25a386a86285713b9555a60f795059b"},
+    {file = "jupyterlab-3.0.15-py3-none-any.whl", hash = "sha256:7ebc32e927b114e3f27250b3d5829ff21507ef81329e53e29338fa4d1a7680f8"},
+    {file = "jupyterlab-3.0.15.tar.gz", hash = "sha256:8e7a1537b39d27ff00666c8ec022e41ecba6669168dd6f8a145941d6b4ec4ca4"},
 ]
 jupyterlab-pygments = [
     {file = "jupyterlab_pygments-0.1.2-py2.py3-none-any.whl", hash = "sha256:abfb880fd1561987efaefcb2d2ac75145d2a5d0139b1876d5be806e32f630008"},
     {file = "jupyterlab_pygments-0.1.2.tar.gz", hash = "sha256:cfcda0873626150932f438eccf0f8bf22bfa92345b814890ab360d666b254146"},
 ]
 jupyterlab-server = [
-    {file = "jupyterlab_server-2.4.0-py3-none-any.whl", hash = "sha256:94e606edb7b60e3fc54b8b4de14cded1483959361df9023e50092b6f8ede9cf6"},
-    {file = "jupyterlab_server-2.4.0.tar.gz", hash = "sha256:2a7f0b125a59a7cc543f62e5f9dea50b44b3459b3f679db7e3dbe0f8616f90bc"},
+    {file = "jupyterlab_server-2.5.1-py3-none-any.whl", hash = "sha256:4a878393f00841c96c871e8eb73131ee6dab1ca18ab3a01fe6859f29f0b1a9e3"},
+    {file = "jupyterlab_server-2.5.1.tar.gz", hash = "sha256:52a08d92d5ce40623a6c5b657deafcb65a8f62c603259aceab57b57cf5432b9b"},
 ]
 jupyterlab-widgets = [
     {file = "jupyterlab_widgets-1.0.0-py3-none-any.whl", hash = "sha256:caeaf3e6103180e654e7d8d2b81b7d645e59e432487c1d35a41d6d3ee56b3fef"},
@@ -1591,79 +1600,65 @@ kiwisolver = [
     {file = "kiwisolver-1.3.1.tar.gz", hash = "sha256:950a199911a8d94683a6b10321f9345d5a3a8433ec58b217ace979e18f16e248"},
 ]
 markupsafe = [
-    {file = "MarkupSafe-1.1.1-cp27-cp27m-macosx_10_6_intel.whl", hash = "sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161"},
-    {file = "MarkupSafe-1.1.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7"},
-    {file = "MarkupSafe-1.1.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183"},
-    {file = "MarkupSafe-1.1.1-cp27-cp27m-win32.whl", hash = "sha256:b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b"},
-    {file = "MarkupSafe-1.1.1-cp27-cp27m-win_amd64.whl", hash = "sha256:98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e"},
-    {file = "MarkupSafe-1.1.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f"},
-    {file = "MarkupSafe-1.1.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1"},
-    {file = "MarkupSafe-1.1.1-cp34-cp34m-macosx_10_6_intel.whl", hash = "sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5"},
-    {file = "MarkupSafe-1.1.1-cp34-cp34m-manylinux1_i686.whl", hash = "sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1"},
-    {file = "MarkupSafe-1.1.1-cp34-cp34m-manylinux1_x86_64.whl", hash = "sha256:88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735"},
-    {file = "MarkupSafe-1.1.1-cp34-cp34m-win32.whl", hash = "sha256:ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21"},
-    {file = "MarkupSafe-1.1.1-cp34-cp34m-win_amd64.whl", hash = "sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235"},
-    {file = "MarkupSafe-1.1.1-cp35-cp35m-macosx_10_6_intel.whl", hash = "sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b"},
-    {file = "MarkupSafe-1.1.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f"},
-    {file = "MarkupSafe-1.1.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905"},
-    {file = "MarkupSafe-1.1.1-cp35-cp35m-win32.whl", hash = "sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1"},
-    {file = "MarkupSafe-1.1.1-cp35-cp35m-win_amd64.whl", hash = "sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d"},
-    {file = "MarkupSafe-1.1.1-cp36-cp36m-macosx_10_6_intel.whl", hash = "sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff"},
-    {file = "MarkupSafe-1.1.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d53bc011414228441014aa71dbec320c66468c1030aae3a6e29778a3382d96e5"},
-    {file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473"},
-    {file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e"},
-    {file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:3b8a6499709d29c2e2399569d96719a1b21dcd94410a586a18526b143ec8470f"},
-    {file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:84dee80c15f1b560d55bcfe6d47b27d070b4681c699c572af2e3c7cc90a3b8e0"},
-    {file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:b1dba4527182c95a0db8b6060cc98ac49b9e2f5e64320e2b56e47cb2831978c7"},
-    {file = "MarkupSafe-1.1.1-cp36-cp36m-win32.whl", hash = "sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66"},
-    {file = "MarkupSafe-1.1.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5"},
-    {file = "MarkupSafe-1.1.1-cp37-cp37m-macosx_10_6_intel.whl", hash = "sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d"},
-    {file = "MarkupSafe-1.1.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:bf5aa3cbcfdf57fa2ee9cd1822c862ef23037f5c832ad09cfea57fa846dec193"},
-    {file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e"},
-    {file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6"},
-    {file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:6fffc775d90dcc9aed1b89219549b329a9250d918fd0b8fa8d93d154918422e1"},
-    {file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:a6a744282b7718a2a62d2ed9d993cad6f5f585605ad352c11de459f4108df0a1"},
-    {file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:195d7d2c4fbb0ee8139a6cf67194f3973a6b3042d742ebe0a9ed36d8b6f0c07f"},
-    {file = "MarkupSafe-1.1.1-cp37-cp37m-win32.whl", hash = "sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2"},
-    {file = "MarkupSafe-1.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c"},
-    {file = "MarkupSafe-1.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6788b695d50a51edb699cb55e35487e430fa21f1ed838122d722e0ff0ac5ba15"},
-    {file = "MarkupSafe-1.1.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:cdb132fc825c38e1aeec2c8aa9338310d29d337bebbd7baa06889d09a60a1fa2"},
-    {file = "MarkupSafe-1.1.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:13d3144e1e340870b25e7b10b98d779608c02016d5184cfb9927a9f10c689f42"},
-    {file = "MarkupSafe-1.1.1-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:acf08ac40292838b3cbbb06cfe9b2cb9ec78fce8baca31ddb87aaac2e2dc3bc2"},
-    {file = "MarkupSafe-1.1.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:d9be0ba6c527163cbed5e0857c451fcd092ce83947944d6c14bc95441203f032"},
-    {file = "MarkupSafe-1.1.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:caabedc8323f1e93231b52fc32bdcde6db817623d33e100708d9a68e1f53b26b"},
-    {file = "MarkupSafe-1.1.1-cp38-cp38-win32.whl", hash = "sha256:596510de112c685489095da617b5bcbbac7dd6384aeebeda4df6025d0256a81b"},
-    {file = "MarkupSafe-1.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:e8313f01ba26fbbe36c7be1966a7b7424942f670f38e666995b88d012765b9be"},
-    {file = "MarkupSafe-1.1.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d73a845f227b0bfe8a7455ee623525ee656a9e2e749e4742706d80a6065d5e2c"},
-    {file = "MarkupSafe-1.1.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:98bae9582248d6cf62321dcb52aaf5d9adf0bad3b40582925ef7c7f0ed85fceb"},
-    {file = "MarkupSafe-1.1.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:2beec1e0de6924ea551859edb9e7679da6e4870d32cb766240ce17e0a0ba2014"},
-    {file = "MarkupSafe-1.1.1-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:7fed13866cf14bba33e7176717346713881f56d9d2bcebab207f7a036f41b850"},
-    {file = "MarkupSafe-1.1.1-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:6f1e273a344928347c1290119b493a1f0303c52f5a5eae5f16d74f48c15d4a85"},
-    {file = "MarkupSafe-1.1.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:feb7b34d6325451ef96bc0e36e1a6c0c1c64bc1fbec4b854f4529e51887b1621"},
-    {file = "MarkupSafe-1.1.1-cp39-cp39-win32.whl", hash = "sha256:22c178a091fc6630d0d045bdb5992d2dfe14e3259760e713c490da5323866c39"},
-    {file = "MarkupSafe-1.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:b7d644ddb4dbd407d31ffb699f1d140bc35478da613b441c582aeb7c43838dd8"},
-    {file = "MarkupSafe-1.1.1.tar.gz", hash = "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b"},
+    {file = "MarkupSafe-2.0.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:2efaeb1baff547063bad2b2893a8f5e9c459c4624e1a96644bbba08910ae34e0"},
+    {file = "MarkupSafe-2.0.0-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:441ce2a8c17683d97e06447fcbccbdb057cbf587c78eb75ae43ea7858042fe2c"},
+    {file = "MarkupSafe-2.0.0-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:45535241baa0fc0ba2a43961a1ac7562ca3257f46c4c3e9c0de38b722be41bd1"},
+    {file = "MarkupSafe-2.0.0-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:90053234a6479738fd40d155268af631c7fca33365f964f2208867da1349294b"},
+    {file = "MarkupSafe-2.0.0-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:3b54a9c68995ef4164567e2cd1a5e16db5dac30b2a50c39c82db8d4afaf14f63"},
+    {file = "MarkupSafe-2.0.0-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:f58b5ba13a5689ca8317b98439fccfbcc673acaaf8241c1869ceea40f5d585bf"},
+    {file = "MarkupSafe-2.0.0-cp36-cp36m-win32.whl", hash = "sha256:a00dce2d96587651ef4fa192c17e039e8cfab63087c67e7d263a5533c7dad715"},
+    {file = "MarkupSafe-2.0.0-cp36-cp36m-win_amd64.whl", hash = "sha256:007dc055dbce5b1104876acee177dbfd18757e19d562cd440182e1f492e96b95"},
+    {file = "MarkupSafe-2.0.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a08cd07d3c3c17cd33d9e66ea9dee8f8fc1c48e2d11bd88fd2dc515a602c709b"},
+    {file = "MarkupSafe-2.0.0-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:3c352ff634e289061711608f5e474ec38dbaa21e3e168820d53d5f4015e5b91b"},
+    {file = "MarkupSafe-2.0.0-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:32200f562daaab472921a11cbb63780f1654552ae49518196fc361ed8e12e901"},
+    {file = "MarkupSafe-2.0.0-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:fef86115fdad7ae774720d7103aa776144cf9b66673b4afa9bcaa7af990ed07b"},
+    {file = "MarkupSafe-2.0.0-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:e79212d09fc0e224d20b43ad44bb0a0a3416d1e04cf6b45fed265114a5d43d20"},
+    {file = "MarkupSafe-2.0.0-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:79b2ae94fa991be023832e6bcc00f41dbc8e5fe9d997a02db965831402551730"},
+    {file = "MarkupSafe-2.0.0-cp37-cp37m-win32.whl", hash = "sha256:3261fae28155e5c8634dd7710635fe540a05b58f160cef7713c7700cb9980e66"},
+    {file = "MarkupSafe-2.0.0-cp37-cp37m-win_amd64.whl", hash = "sha256:e4570d16f88c7f3032ed909dc9e905a17da14a1c4cfd92608e3fda4cb1208bbd"},
+    {file = "MarkupSafe-2.0.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8f806bfd0f218477d7c46a11d3e52dc7f5fdfaa981b18202b7dc84bbc287463b"},
+    {file = "MarkupSafe-2.0.0-cp38-cp38-manylinux1_i686.whl", hash = "sha256:e77e4b983e2441aff0c0d07ee711110c106b625f440292dfe02a2f60c8218bd6"},
+    {file = "MarkupSafe-2.0.0-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:031bf79a27d1c42f69c276d6221172417b47cb4b31cdc73d362a9bf5a1889b9f"},
+    {file = "MarkupSafe-2.0.0-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:83cf0228b2f694dcdba1374d5312f2277269d798e65f40344964f642935feac1"},
+    {file = "MarkupSafe-2.0.0-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:4cc563836f13c57f1473bc02d1e01fc37bab70ad4ee6be297d58c1d66bc819bf"},
+    {file = "MarkupSafe-2.0.0-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:d00a669e4a5bec3ee6dbeeeedd82a405ced19f8aeefb109a012ea88a45afff96"},
+    {file = "MarkupSafe-2.0.0-cp38-cp38-win32.whl", hash = "sha256:161d575fa49395860b75da5135162481768b11208490d5a2143ae6785123e77d"},
+    {file = "MarkupSafe-2.0.0-cp38-cp38-win_amd64.whl", hash = "sha256:58bc9fce3e1557d463ef5cee05391a05745fd95ed660f23c1742c711712c0abb"},
+    {file = "MarkupSafe-2.0.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:3fb47f97f1d338b943126e90b79cad50d4fcfa0b80637b5a9f468941dbbd9ce5"},
+    {file = "MarkupSafe-2.0.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:dab0c685f21f4a6c95bfc2afd1e7eae0033b403dd3d8c1b6d13a652ada75b348"},
+    {file = "MarkupSafe-2.0.0-cp39-cp39-manylinux1_i686.whl", hash = "sha256:664832fb88b8162268928df233f4b12a144a0c78b01d38b81bdcf0fc96668ecb"},
+    {file = "MarkupSafe-2.0.0-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:df561f65049ed3556e5b52541669310e88713fdae2934845ec3606f283337958"},
+    {file = "MarkupSafe-2.0.0-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:24bbc3507fb6dfff663af7900a631f2aca90d5a445f272db5fc84999fa5718bc"},
+    {file = "MarkupSafe-2.0.0-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:87de598edfa2230ff274c4de7fcf24c73ffd96208c8e1912d5d0fee459767d75"},
+    {file = "MarkupSafe-2.0.0-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:a19d39b02a24d3082856a5b06490b714a9d4179321225bbf22809ff1e1887cc8"},
+    {file = "MarkupSafe-2.0.0-cp39-cp39-win32.whl", hash = "sha256:4aca81a687975b35e3e80bcf9aa93fe10cd57fac37bf18b2314c186095f57e05"},
+    {file = "MarkupSafe-2.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:70820a1c96311e02449591cbdf5cd1c6a34d5194d5b55094ab725364375c9eb2"},
+    {file = "MarkupSafe-2.0.0.tar.gz", hash = "sha256:4fae0677f712ee090721d8b17f412f1cbceefbf0dc180fe91bab3232f38b4527"},
 ]
 matplotlib = [
-    {file = "matplotlib-3.4.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:7a54efd6fcad9cb3cd5ef2064b5a3eeb0b63c99f26c346bdcf66e7c98294d7cc"},
-    {file = "matplotlib-3.4.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:86dc94e44403fa0f2b1dd76c9794d66a34e821361962fe7c4e078746362e3b14"},
-    {file = "matplotlib-3.4.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:574306171b84cd6854c83dc87bc353cacc0f60184149fb00c9ea871eca8c1ecb"},
-    {file = "matplotlib-3.4.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:84a10e462120aa7d9eb6186b50917ed5a6286ee61157bfc17c5b47987d1a9068"},
-    {file = "matplotlib-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:81e6fe8b18ef5be67f40a1d4f07d5a4ed21d3878530193898449ddef7793952f"},
-    {file = "matplotlib-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:c45e7bf89ea33a2adaef34774df4e692c7436a18a48bcb0e47a53e698a39fa39"},
-    {file = "matplotlib-3.4.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1f83a32e4b6045191f9d34e4dc68c0a17c870b57ef9cca518e516da591246e79"},
-    {file = "matplotlib-3.4.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:a18cc1ab4a35b845cf33b7880c979f5c609fd26c2d6e74ddfacb73dcc60dd956"},
-    {file = "matplotlib-3.4.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:ac2a30a09984c2719f112a574b6543ccb82d020fd1b23b4d55bf4759ba8dd8f5"},
-    {file = "matplotlib-3.4.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:a97781453ac79409ddf455fccf344860719d95142f9c334f2a8f3fff049ffec3"},
-    {file = "matplotlib-3.4.1-cp38-cp38-win32.whl", hash = "sha256:2eee37340ca1b353e0a43a33da79d0cd4bcb087064a0c3c3d1329cdea8fbc6f3"},
-    {file = "matplotlib-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:90dbc007f6389bcfd9ef4fe5d4c78c8d2efe4e0ebefd48b4f221cdfed5672be2"},
-    {file = "matplotlib-3.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7f16660edf9a8bcc0f766f51c9e1b9d2dc6ceff6bf636d2dbd8eb925d5832dfd"},
-    {file = "matplotlib-3.4.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:a989022f89cda417f82dbf65e0a830832afd8af743d05d1414fb49549287ff04"},
-    {file = "matplotlib-3.4.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:be4430b33b25e127fc4ea239cc386389de420be4d63e71d5359c20b562951ce1"},
-    {file = "matplotlib-3.4.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:7561fd541477d41f3aa09457c434dd1f7604f3bd26d7858d52018f5dfe1c06d1"},
-    {file = "matplotlib-3.4.1-cp39-cp39-win32.whl", hash = "sha256:9f374961a3996c2d1b41ba3145462c3708a89759e604112073ed6c8bdf9f622f"},
-    {file = "matplotlib-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:53ceb12ef44f8982b45adc7a0889a7e2df1d758e8b360f460e435abe8a8cd658"},
-    {file = "matplotlib-3.4.1.tar.gz", hash = "sha256:84d4c4f650f356678a5d658a43ca21a41fca13f9b8b00169c0b76e6a6a948908"},
+    {file = "matplotlib-3.4.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c541ee5a3287efe066bbe358320853cf4916bc14c00c38f8f3d8d75275a405a9"},
+    {file = "matplotlib-3.4.2-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:3a5c18dbd2c7c366da26a4ad1462fe3e03a577b39e3b503bbcf482b9cdac093c"},
+    {file = "matplotlib-3.4.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:a9d8cb5329df13e0cdaa14b3b43f47b5e593ec637f13f14db75bb16e46178b05"},
+    {file = "matplotlib-3.4.2-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:7ad19f3fb6145b9eb41c08e7cbb9f8e10b91291396bee21e9ce761bb78df63ec"},
+    {file = "matplotlib-3.4.2-cp37-cp37m-win32.whl", hash = "sha256:7a58f3d8fe8fac3be522c79d921c9b86e090a59637cb88e3bc51298d7a2c862a"},
+    {file = "matplotlib-3.4.2-cp37-cp37m-win_amd64.whl", hash = "sha256:6382bc6e2d7e481bcd977eb131c31dee96e0fb4f9177d15ec6fb976d3b9ace1a"},
+    {file = "matplotlib-3.4.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6a6a44f27aabe720ec4fd485061e8a35784c2b9ffa6363ad546316dfc9cea04e"},
+    {file = "matplotlib-3.4.2-cp38-cp38-manylinux1_i686.whl", hash = "sha256:1c1779f7ab7d8bdb7d4c605e6ffaa0614b3e80f1e3c8ccf7b9269a22dbc5986b"},
+    {file = "matplotlib-3.4.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:5826f56055b9b1c80fef82e326097e34dc4af8c7249226b7dd63095a686177d1"},
+    {file = "matplotlib-3.4.2-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:0bea5ec5c28d49020e5d7923c2725b837e60bc8be99d3164af410eb4b4c827da"},
+    {file = "matplotlib-3.4.2-cp38-cp38-win32.whl", hash = "sha256:6475d0209024a77f869163ec3657c47fed35d9b6ed8bccba8aa0f0099fbbdaa8"},
+    {file = "matplotlib-3.4.2-cp38-cp38-win_amd64.whl", hash = "sha256:21b31057bbc5e75b08e70a43cefc4c0b2c2f1b1a850f4a0f7af044eb4163086c"},
+    {file = "matplotlib-3.4.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b26535b9de85326e6958cdef720ecd10bcf74a3f4371bf9a7e5b2e659c17e153"},
+    {file = "matplotlib-3.4.2-cp39-cp39-manylinux1_i686.whl", hash = "sha256:32fa638cc10886885d1ca3d409d4473d6a22f7ceecd11322150961a70fab66dd"},
+    {file = "matplotlib-3.4.2-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:956c8849b134b4a343598305a3ca1bdd3094f01f5efc8afccdebeffe6b315247"},
+    {file = "matplotlib-3.4.2-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:85f191bb03cb1a7b04b5c2cca4792bef94df06ef473bc49e2818105671766fee"},
+    {file = "matplotlib-3.4.2-cp39-cp39-win32.whl", hash = "sha256:b1d5a2cedf5de05567c441b3a8c2651fbde56df08b82640e7f06c8cd91e201f6"},
+    {file = "matplotlib-3.4.2-cp39-cp39-win_amd64.whl", hash = "sha256:df815378a754a7edd4559f8c51fc7064f779a74013644a7f5ac7a0c31f875866"},
+    {file = "matplotlib-3.4.2.tar.gz", hash = "sha256:d8d994cefdff9aaba45166eb3de4f5211adb4accac85cbf97137e98f26ea0219"},
+]
+matplotlib-inline = [
+    {file = "matplotlib-inline-0.1.2.tar.gz", hash = "sha256:f41d5ff73c9f5385775d5c0bc13b424535c8402fe70ea8210f93e11f3683993e"},
+    {file = "matplotlib_inline-0.1.2-py3-none-any.whl", hash = "sha256:5cf1176f554abb4fa98cb362aa2b55c500147e4bdbb07e3fda359143e1da0811"},
 ]
 mistune = [
     {file = "mistune-0.8.4-py2.py3-none-any.whl", hash = "sha256:88a1051873018da288eee8538d476dffe1262495144b33ecb586c4ab266bb8d4"},
@@ -1674,8 +1669,8 @@ mpmath = [
     {file = "mpmath-1.2.1.tar.gz", hash = "sha256:79ffb45cf9f4b101a807595bcb3e72e0396202e0b1d25d689134b48c4216a81a"},
 ]
 nbclassic = [
-    {file = "nbclassic-0.2.7-py3-none-any.whl", hash = "sha256:8843cafa3827db05b9e7da909a4955b552de13e20707474844cfdd84bf4bf655"},
-    {file = "nbclassic-0.2.7.tar.gz", hash = "sha256:6835b27ffaed1f7a497371bb2c05c0f2b123cbcf7c3c116c1ca808ac78ac2fe8"},
+    {file = "nbclassic-0.2.8-py3-none-any.whl", hash = "sha256:3ef68acb3b917d3ae0201848dababecfcf8a888549cb09037f0c7a27557dc2e0"},
+    {file = "nbclassic-0.2.8.tar.gz", hash = "sha256:9553dcd9ae4d932db640dad0daa186fe6c64e69ec2159868c0b38d7adef9b3b5"},
 ]
 nbclient = [
     {file = "nbclient-0.5.3-py3-none-any.whl", hash = "sha256:e79437364a2376892b3f46bedbf9b444e5396cfb1bc366a472c37b48e9551500"},
@@ -1701,30 +1696,30 @@ notebook = [
     {file = "notebook-6.3.0.tar.gz", hash = "sha256:cbc9398d6c81473e9cdb891d2cae9c0d3718fca289dda6d26df5cb660fcadc7d"},
 ]
 numpy = [
-    {file = "numpy-1.20.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:e9459f40244bb02b2f14f6af0cd0732791d72232bbb0dc4bab57ef88e75f6935"},
-    {file = "numpy-1.20.2-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:a8e6859913ec8eeef3dbe9aed3bf475347642d1cdd6217c30f28dee8903528e6"},
-    {file = "numpy-1.20.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:9cab23439eb1ebfed1aaec9cd42b7dc50fc96d5cd3147da348d9161f0501ada5"},
-    {file = "numpy-1.20.2-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:9c0fab855ae790ca74b27e55240fe4f2a36a364a3f1ebcfd1fb5ac4088f1cec3"},
-    {file = "numpy-1.20.2-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:61d5b4cf73622e4d0c6b83408a16631b670fc045afd6540679aa35591a17fe6d"},
-    {file = "numpy-1.20.2-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:d15007f857d6995db15195217afdbddfcd203dfaa0ba6878a2f580eaf810ecd6"},
-    {file = "numpy-1.20.2-cp37-cp37m-win32.whl", hash = "sha256:d76061ae5cab49b83a8cf3feacefc2053fac672728802ac137dd8c4123397677"},
-    {file = "numpy-1.20.2-cp37-cp37m-win_amd64.whl", hash = "sha256:bad70051de2c50b1a6259a6df1daaafe8c480ca98132da98976d8591c412e737"},
-    {file = "numpy-1.20.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:719656636c48be22c23641859ff2419b27b6bdf844b36a2447cb39caceb00935"},
-    {file = "numpy-1.20.2-cp38-cp38-manylinux1_i686.whl", hash = "sha256:aa046527c04688af680217fffac61eec2350ef3f3d7320c07fd33f5c6e7b4d5f"},
-    {file = "numpy-1.20.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:2428b109306075d89d21135bdd6b785f132a1f5a3260c371cee1fae427e12727"},
-    {file = "numpy-1.20.2-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:e8e4fbbb7e7634f263c5b0150a629342cc19b47c5eba8d1cd4363ab3455ab576"},
-    {file = "numpy-1.20.2-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:edb1f041a9146dcf02cd7df7187db46ab524b9af2515f392f337c7cbbf5b52cd"},
-    {file = "numpy-1.20.2-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:c73a7975d77f15f7f68dacfb2bca3d3f479f158313642e8ea9058eea06637931"},
-    {file = "numpy-1.20.2-cp38-cp38-win32.whl", hash = "sha256:6c915ee7dba1071554e70a3664a839fbc033e1d6528199d4621eeaaa5487ccd2"},
-    {file = "numpy-1.20.2-cp38-cp38-win_amd64.whl", hash = "sha256:471c0571d0895c68da309dacee4e95a0811d0a9f9f532a48dc1bea5f3b7ad2b7"},
-    {file = "numpy-1.20.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4703b9e937df83f5b6b7447ca5912b5f5f297aba45f91dbbbc63ff9278c7aa98"},
-    {file = "numpy-1.20.2-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:abc81829c4039e7e4c30f7897938fa5d4916a09c2c7eb9b244b7a35ddc9656f4"},
-    {file = "numpy-1.20.2-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:377751954da04d4a6950191b20539066b4e19e3b559d4695399c5e8e3e683bf6"},
-    {file = "numpy-1.20.2-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:6e51e417d9ae2e7848314994e6fc3832c9d426abce9328cf7571eefceb43e6c9"},
-    {file = "numpy-1.20.2-cp39-cp39-win32.whl", hash = "sha256:780ae5284cb770ade51d4b4a7dce4faa554eb1d88a56d0e8b9f35fca9b0270ff"},
-    {file = "numpy-1.20.2-cp39-cp39-win_amd64.whl", hash = "sha256:924dc3f83de20437de95a73516f36e09918e9c9c18d5eac520062c49191025fb"},
-    {file = "numpy-1.20.2-pp37-pypy37_pp73-manylinux2010_x86_64.whl", hash = "sha256:97ce8b8ace7d3b9288d88177e66ee75480fb79b9cf745e91ecfe65d91a856042"},
-    {file = "numpy-1.20.2.zip", hash = "sha256:878922bf5ad7550aa044aa9301d417e2d3ae50f0f577de92051d739ac6096cee"},
+    {file = "numpy-1.20.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:70eb5808127284c4e5c9e836208e09d685a7978b6a216db85960b1a112eeace8"},
+    {file = "numpy-1.20.3-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:6ca2b85a5997dabc38301a22ee43c82adcb53ff660b89ee88dded6b33687e1d8"},
+    {file = "numpy-1.20.3-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c5bf0e132acf7557fc9bb8ded8b53bbbbea8892f3c9a1738205878ca9434206a"},
+    {file = "numpy-1.20.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:db250fd3e90117e0312b611574cd1b3f78bec046783195075cbd7ba9c3d73f16"},
+    {file = "numpy-1.20.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:637d827248f447e63585ca3f4a7d2dfaa882e094df6cfa177cc9cf9cd6cdf6d2"},
+    {file = "numpy-1.20.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:8b7bb4b9280da3b2856cb1fc425932f46fba609819ee1c62256f61799e6a51d2"},
+    {file = "numpy-1.20.3-cp37-cp37m-win32.whl", hash = "sha256:67d44acb72c31a97a3d5d33d103ab06d8ac20770e1c5ad81bdb3f0c086a56cf6"},
+    {file = "numpy-1.20.3-cp37-cp37m-win_amd64.whl", hash = "sha256:43909c8bb289c382170e0282158a38cf306a8ad2ff6dfadc447e90f9961bef43"},
+    {file = "numpy-1.20.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f1452578d0516283c87608a5a5548b0cdde15b99650efdfd85182102ef7a7c17"},
+    {file = "numpy-1.20.3-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:6e51534e78d14b4a009a062641f465cfaba4fdcb046c3ac0b1f61dd97c861b1b"},
+    {file = "numpy-1.20.3-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e515c9a93aebe27166ec9593411c58494fa98e5fcc219e47260d9ab8a1cc7f9f"},
+    {file = "numpy-1.20.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c1c09247ccea742525bdb5f4b5ceeacb34f95731647fe55774aa36557dbb5fa4"},
+    {file = "numpy-1.20.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:66fbc6fed94a13b9801fb70b96ff30605ab0a123e775a5e7a26938b717c5d71a"},
+    {file = "numpy-1.20.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:ea9cff01e75a956dbee133fa8e5b68f2f92175233de2f88de3a682dd94deda65"},
+    {file = "numpy-1.20.3-cp38-cp38-win32.whl", hash = "sha256:f39a995e47cb8649673cfa0579fbdd1cdd33ea497d1728a6cb194d6252268e48"},
+    {file = "numpy-1.20.3-cp38-cp38-win_amd64.whl", hash = "sha256:1676b0a292dd3c99e49305a16d7a9f42a4ab60ec522eac0d3dd20cdf362ac010"},
+    {file = "numpy-1.20.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:830b044f4e64a76ba71448fce6e604c0fc47a0e54d8f6467be23749ac2cbd2fb"},
+    {file = "numpy-1.20.3-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:55b745fca0a5ab738647d0e4db099bd0a23279c32b31a783ad2ccea729e632df"},
+    {file = "numpy-1.20.3-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:5d050e1e4bc9ddb8656d7b4f414557720ddcca23a5b88dd7cff65e847864c400"},
+    {file = "numpy-1.20.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a9c65473ebc342715cb2d7926ff1e202c26376c0dcaaee85a1fd4b8d8c1d3b2f"},
+    {file = "numpy-1.20.3-cp39-cp39-win32.whl", hash = "sha256:16f221035e8bd19b9dc9a57159e38d2dd060b48e93e1d843c49cb370b0f415fd"},
+    {file = "numpy-1.20.3-cp39-cp39-win_amd64.whl", hash = "sha256:6690080810f77485667bfbff4f69d717c3be25e5b11bb2073e76bb3f578d99b4"},
+    {file = "numpy-1.20.3-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4e465afc3b96dbc80cf4a5273e5e2b1e3451286361b4af70ce1adb2984d392f9"},
+    {file = "numpy-1.20.3.zip", hash = "sha256:e55185e51b18d788e49fe8305fd73ef4470596b33fc2c1ceb304566b99c71a69"},
 ]
 packaging = [
     {file = "packaging-20.9-py2.py3-none-any.whl", hash = "sha256:67714da7f7bc052e064859c05c595155bd1ee9f69f76557e21f051443c20947a"},
@@ -1805,8 +1800,8 @@ pycparser = [
     {file = "pycparser-2.20.tar.gz", hash = "sha256:2d475327684562c3a96cc71adf7dc8c4f0565175cf86b6d7a404ff4c771f15f0"},
 ]
 pygments = [
-    {file = "Pygments-2.8.1-py3-none-any.whl", hash = "sha256:534ef71d539ae97d4c3a4cf7d6f110f214b0e687e92f9cb9d2a3b0d3101289c8"},
-    {file = "Pygments-2.8.1.tar.gz", hash = "sha256:2656e1a6edcdabf4275f9a3640db59fd5de107d88e8663c5d4e9a0fa62f77f94"},
+    {file = "Pygments-2.9.0-py3-none-any.whl", hash = "sha256:d66e804411278594d764fc69ec36ec13d9ae9147193a1740cd34d272ca383b8e"},
+    {file = "Pygments-2.9.0.tar.gz", hash = "sha256:a18f47b506a429f6f4b9df81bb02beab9ca21d0a5fee38ed15aef65f0545519f"},
 ]
 pyparsing = [
     {file = "pyparsing-2.4.7-py2.py3-none-any.whl", hash = "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"},
@@ -1816,8 +1811,8 @@ pyrsistent = [
     {file = "pyrsistent-0.17.3.tar.gz", hash = "sha256:2e636185d9eb976a18a8a8e96efce62f2905fea90041958d8cc2a189756ebf3e"},
 ]
 pytest = [
-    {file = "pytest-6.2.3-py3-none-any.whl", hash = "sha256:6ad9c7bdf517a808242b998ac20063c41532a570d088d77eec1ee12b0b5574bc"},
-    {file = "pytest-6.2.3.tar.gz", hash = "sha256:671238a46e4df0f3498d1c3270e5deb9b32d25134c99b7d75370a68cfbe9b634"},
+    {file = "pytest-6.2.4-py3-none-any.whl", hash = "sha256:91ef2131a9bd6be8f76f1f08eac5c5317221d6ad1e143ae03894b862e8976890"},
+    {file = "pytest-6.2.4.tar.gz", hash = "sha256:50bcad0a0b9c5a72c8e4e7c9855a3ad496ca6a881a3641b4260605450772c54b"},
 ]
 python-dateutil = [
     {file = "python-dateutil-2.8.1.tar.gz", hash = "sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c"},
@@ -1917,8 +1912,8 @@ pyzmq = [
     {file = "pyzmq-22.0.3.tar.gz", hash = "sha256:f7f63ce127980d40f3e6a5fdb87abf17ce1a7c2bd8bf2c7560e1bbce8ab1f92d"},
 ]
 qtconsole = [
-    {file = "qtconsole-5.0.3-py3-none-any.whl", hash = "sha256:4a38053993ca2da058f76f8d75b3d8906efbf9183de516f92f222ac8e37d9614"},
-    {file = "qtconsole-5.0.3.tar.gz", hash = "sha256:c091a35607d2a2432e004c4a112d241ce908086570cf68594176dd52ccaa212d"},
+    {file = "qtconsole-5.1.0-py3-none-any.whl", hash = "sha256:3a2adecc43ff201a08972fb2179df22e7b3a08d71b9ed680f46ad1bfd4fb9132"},
+    {file = "qtconsole-5.1.0.tar.gz", hash = "sha256:12c734494901658787339dea9bbd82f3dc0d5e394071377a1c77b4a0954d7d8b"},
 ]
 qtpy = [
     {file = "QtPy-1.9.0-py2.py3-none-any.whl", hash = "sha256:fa0b8363b363e89b2a6f49eddc162a04c0699ae95e109a6be3bb145a913190ea"},
@@ -1929,16 +1924,16 @@ recommonmark = [
     {file = "recommonmark-0.6.0.tar.gz", hash = "sha256:29cd4faeb6c5268c633634f2d69aef9431e0f4d347f90659fd0aab20e541efeb"},
 ]
 requests = [
-    {file = "requests-2.15.1-py2.py3-none-any.whl", hash = "sha256:ff753b2196cd18b1bbeddc9dcd5c864056599f7a7d9a4fb5677e723efa2b7fb9"},
-    {file = "requests-2.15.1.tar.gz", hash = "sha256:e5659b9315a0610505e050bb7190bf6fa2ccee1ac295f2b760ef9d8a03ebbb2e"},
+    {file = "requests-2.25.1-py2.py3-none-any.whl", hash = "sha256:c210084e36a42ae6b9219e00e48287def368a26d03a048ddad7bfee44f75871e"},
+    {file = "requests-2.25.1.tar.gz", hash = "sha256:27973dd4a904a4f13b263a19c866c13b92a39ed1c964655f025f3f8d3d75b804"},
 ]
 send2trash = [
     {file = "Send2Trash-1.5.0-py3-none-any.whl", hash = "sha256:f1691922577b6fa12821234aeb57599d887c4900b9ca537948d2dac34aea888b"},
     {file = "Send2Trash-1.5.0.tar.gz", hash = "sha256:60001cc07d707fe247c94f74ca6ac0d3255aabcb930529690897ca2a39db28b2"},
 ]
 six = [
-    {file = "six-1.15.0-py2.py3-none-any.whl", hash = "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced"},
-    {file = "six-1.15.0.tar.gz", hash = "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259"},
+    {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
+    {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
 ]
 sniffio = [
     {file = "sniffio-1.2.0-py3-none-any.whl", hash = "sha256:471b71698eac1c2112a40ce2752bb2f4a4814c22a54a3eed3676bc0f5ca9f663"},
@@ -1956,10 +1951,6 @@ sphinx = [
     {file = "Sphinx-3.5.3-py3-none-any.whl", hash = "sha256:3f01732296465648da43dec8fb40dc451ba79eb3e2cc5c6d79005fd98197107d"},
     {file = "Sphinx-3.5.3.tar.gz", hash = "sha256:ce9c228456131bab09a3d7d10ae58474de562a6f79abb3dc811ae401cf8c1abc"},
 ]
-sphinx-rtd-theme = [
-    {file = "sphinx_rtd_theme-0.4.3-py2.py3-none-any.whl", hash = "sha256:00cf895504a7895ee433807c62094cf1e95f065843bf3acd17037c3e9a2becd4"},
-    {file = "sphinx_rtd_theme-0.4.3.tar.gz", hash = "sha256:728607e34d60456d736cc7991fd236afb828b21b82f956c5ea75f94c8414040a"},
-]
 sphinxcontrib-applehelp = [
     {file = "sphinxcontrib-applehelp-1.0.2.tar.gz", hash = "sha256:a072735ec80e7675e3f432fcae8610ecf509c5f1869d17e2eecff44389cdbc58"},
     {file = "sphinxcontrib_applehelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:806111e5e962be97c29ec4c1e7fe277bfd19e9652fb1a4392105b43e01af885a"},
@@ -1989,8 +1980,8 @@ sympy = [
     {file = "sympy-1.8.tar.gz", hash = "sha256:1ca588a9f6ce6a323c5592f9635159c2093572826668a1022c75c75bdf0297cb"},
 ]
 terminado = [
-    {file = "terminado-0.9.4-py3-none-any.whl", hash = "sha256:daed77f9fad7b32558fa84b226a76f45a02242c20813502f36c4e1ade6d8f1ad"},
-    {file = "terminado-0.9.4.tar.gz", hash = "sha256:9a7dbcfbc2778830eeb70261bf7aa9d98a3eac8631a3afe3febeb57c12f798be"},
+    {file = "terminado-0.9.5-py3-none-any.whl", hash = "sha256:3838414888b49a96145e277fd707a26a0fdb4bdaba88bb677a44abb68e3a1041"},
+    {file = "terminado-0.9.5.tar.gz", hash = "sha256:54c22cfb47cf79d4ff4ed2e7b5f8f98ecc28d0830f980465b6e04cf09cf553cf"},
 ]
 testpath = [
     {file = "testpath-0.4.4-py2.py3-none-any.whl", hash = "sha256:bfcf9411ef4bf3db7579063e0546938b1edda3d69f4e1fb8756991f5951f85d4"},
@@ -2000,10 +1991,6 @@ toml = [
     {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"},
     {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"},
 ]
-tomlkit = [
-    {file = "tomlkit-0.7.0-py2.py3-none-any.whl", hash = "sha256:6babbd33b17d5c9691896b0e68159215a9387ebfa938aa3ac42f4a4beeb2b831"},
-    {file = "tomlkit-0.7.0.tar.gz", hash = "sha256:ac57f29693fab3e309ea789252fcce3061e19110085aa31af5446ca749325618"},
-]
 toolz = [
     {file = "toolz-0.11.1-py3-none-any.whl", hash = "sha256:1bc473acbf1a1db4e72a1ce587be347450e8f08324908b8a266b486f408f04d5"},
     {file = "toolz-0.11.1.tar.gz", hash = "sha256:c7a47921f07822fe534fb1c01c9931ab335a4390c782bd28c6bcc7c2f71f3fbf"},
@@ -2055,6 +2042,10 @@ traitlets = [
     {file = "traitlets-5.0.5-py3-none-any.whl", hash = "sha256:69ff3f9d5351f31a7ad80443c2674b7099df13cc41fc5fa6e2f6d3b0330b0426"},
     {file = "traitlets-5.0.5.tar.gz", hash = "sha256:178f4ce988f69189f7e523337a3e11d91c786ded9360174a3d9ca83e79bc5396"},
 ]
+urllib3 = [
+    {file = "urllib3-1.26.4-py2.py3-none-any.whl", hash = "sha256:2f4da4594db7e1e110a944bb1b551fdf4e6c136ad42e4234131391e21eb5b0df"},
+    {file = "urllib3-1.26.4.tar.gz", hash = "sha256:e7b021f7241115872f92f43c6508082facffbd1c048e3c6e2bb9c2a157e28937"},
+]
 wcwidth = [
     {file = "wcwidth-0.2.5-py2.py3-none-any.whl", hash = "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784"},
     {file = "wcwidth-0.2.5.tar.gz", hash = "sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83"},
@@ -2063,6 +2054,10 @@ webencodings = [
     {file = "webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78"},
     {file = "webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"},
 ]
+websocket-client = [
+    {file = "websocket-client-0.59.0.tar.gz", hash = "sha256:d376bd60eace9d437ab6d7ee16f4ab4e821c9dae591e1b783c58ebd8aaf80c5c"},
+    {file = "websocket_client-0.59.0-py2.py3-none-any.whl", hash = "sha256:2e50d26ca593f70aba7b13a489435ef88b8fc3b5c5643c1ce8808ff9b40f0b32"},
+]
 widgetsnbextension = [
     {file = "widgetsnbextension-3.5.1-py2.py3-none-any.whl", hash = "sha256:bd314f8ceb488571a5ffea6cc5b9fc6cba0adaf88a9d2386b93a489751938bcd"},
     {file = "widgetsnbextension-3.5.1.tar.gz", hash = "sha256:079f87d87270bce047512400efd70238820751a11d2d8cb137a5a5bdbaf255c7"},
diff --git a/pyproject.toml b/pyproject.toml
index 462abfb..cd486e3 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -28,6 +28,7 @@ name = "nata"
 readme = "README.md"
 repository = "https://github.com/GoLP-IST/nata"
 version = "0.0.2"
+include = ["examples/*"]
 
 [tool.poetry.urls]
 "Bug Tracker" = "https://github.com/GoLP-IST/nata/issues"
@@ -48,10 +49,9 @@ hypothesis = "^5.10.4"
 pytest = ">5.0"
 recommonmark = {version = "^0.6.0", optional = true}
 sphinx = {version = "^3.0.3", optional = true}
-sphinx-rtd-theme = {version = "^0.4.3", optional = true}
 
 [tool.poetry.extras]
-docs = ["sphinx", "sphinx-rtd-theme", "recommonmark"]
+docs = ["sphinx", "recommonmark"]
 jupyter = ["jupyterlab", "ipywidgets", "jupyter"]
 
 [tool.isort]


Test patch:
diff --git a/tests/containers/grid_test.py b/tests/containers/grid_test.py
index 72ba491..ed66e58 100644
--- a/tests/containers/grid_test.py
+++ b/tests/containers/grid_test.py
@@ -245,7 +245,7 @@ def test_GridArray_repr():
         "GridArray<"
         "shape=(4, 3), "
         "dtype=int32, "
-        "time=0.0, "
+        "time=None, "
         "axes=(Axis(axis0), Axis(axis1))"
         ">"
     )
@@ -262,7 +262,7 @@ def test_GridArray_repr_html():
     | **unit**  | '' |
     | **shape** | (4, 3) |
     | **dtype** | int32 |
-    | **time**  | 0.0 |
+    | **time**  | None |
     | **axes**  | Axis(axis0), Axis(axis1) |
 
     """
diff --git a/tests/containers/utils_test.py b/tests/containers/utils_test.py
index ba34e6c..3127bef 100644
--- a/tests/containers/utils_test.py
+++ b/tests/containers/utils_test.py
@@ -1,8 +1,12 @@
 # -*- coding: utf-8 -*-
 import dask.array as da
 import numpy as np
+import pytest
 from numpy.lib import recfunctions
 
+from nata.containers.core import HasNumpyInterface
+from nata.containers.utils import to_dask
+from nata.containers.utils import to_numpy
 from nata.containers.utils import unstructured_to_structured
 
 
@@ -18,3 +22,35 @@ def test_unstructured_to_structured():
 
     assert isinstance(converted_arr, da.Array)
     np.testing.assert_array_equal(converted_arr, expected)
+
+
+def test_to_dask():
+    class ClassWithNumpyInterface(HasNumpyInterface):
+        pass
+
+    class ClassWithoutNumpyInterface:
+        pass
+
+    assert isinstance(to_dask(ClassWithNumpyInterface(da.arange(10))), da.Array)
+
+    with pytest.raises(
+        TypeError,
+        match=r"requires object of type '.*HasNumpyInterface.*'",
+    ):
+        to_dask(ClassWithoutNumpyInterface())
+
+
+def test_to_numpy():
+    class ClassWithNumpyInterface(HasNumpyInterface):
+        pass
+
+    class ClassWithoutNumpyInterface:
+        pass
+
+    assert isinstance(to_numpy(ClassWithNumpyInterface(da.arange(10))), np.ndarray)
+
+    with pytest.raises(
+        TypeError,
+        match=r"requires object of type '.*HasNumpyInterface.*'",
+    ):
+        to_numpy(ClassWithoutNumpyInterface())