Repository: vanderschaarlab/temporai (language: python)

Issue:
Add tutorials(notebooks  + Colab links)
## Description
 - The library should have a tutorial for each major feature.
 - The tutorials should be notebooks, and should be also deployed on Colab, for easier use.



Discussion / hints:
Tutorials and Colab links(https://github.com/vanderschaarlab/temporai/issues/44): first, some notebooks for all the relevant features. Then, after the PyPI deploy, some Colab links for ease of use/testing.

Fix patch:
diff --git a/.gitignore b/.gitignore
index 77600611..53ad6e51 100644
--- a/.gitignore
+++ b/.gitignore
@@ -59,3 +59,5 @@ dev/**
 logs/**
 outputs/**
 data/**
+tutorials/*/data
+tutorials/*/logs
diff --git a/.readthedocs.yml b/.readthedocs.yml
index 6940f655..b55c8e9a 100644
--- a/.readthedocs.yml
+++ b/.readthedocs.yml
@@ -20,5 +20,11 @@ sphinx:
 
 python:
   install:
+    # This should match `prereq.txt`:
+    - method: pip
+      path: torch
+    - method: pip
+      path: numpy
+    # -------------------------------
     - requirements: docs/requirements.txt
     - {path: ., method: pip}
diff --git a/CITATION.cff b/CITATION.cff
new file mode 100644
index 00000000..3b844b73
--- /dev/null
+++ b/CITATION.cff
@@ -0,0 +1,28 @@
+cff-version: 1.2.0
+message: "If you use this software, please cite it using the metadata from this file."
+title: "TemporAI: ML-centric Toolkit for Medical Time Series"
+authors:
+- given-names: Evgeny S.
+  family-names: Saveliev
+  affiliation: 'DAMTP, University of Cambridge'
+  orcid: 'https://orcid.org/0000-0003-2887-0342'
+- given-names: Mihaela
+  family-names: Schaar
+  name-suffix: van der
+  affiliation: 'DAMTP, University of Cambridge'
+  orcid: 'https://orcid.org/0000-0003-3933-6049'
+url: 'https://github.com/vanderschaarlab/temporai/'
+preferred-citation:
+  type: article
+  title: "TemporAI: Facilitating Machine Learning Innovation in Time Domain Tasks for Medicine"
+  authors:
+  - given-names: Evgeny S.
+    family-names: Saveliev
+    affiliation: 'DAMTP, University of Cambridge'
+    orcid: 'https://orcid.org/0000-0003-2887-0342'
+  - given-names: Mihaela
+    family-names: Schaar
+    name-suffix: van der
+    affiliation: 'DAMTP, University of Cambridge'
+    orcid: 'https://orcid.org/0000-0003-3933-6049'
+  url: 'https://arxiv.org/abs/2301.12260'
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index c7966d67..5064d025 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,6 +1,8 @@
 # Contributing
 
-Welcome to *TemporAI* contributor's guide. This is adapted from [PyScaffold] contributor's guide template.
+Welcome to *TemporAI* contributor's guide.
+
+> This guide is adapted from [PyScaffold] contributor's guide template.
 
 This document focuses on getting any potential contributor familiarized with
 the development processes, but [other kinds of contributions] are also appreciated.
@@ -14,6 +16,8 @@ considerate, reasonable, and respectful**. When in doubt,
 [Python Software Foundation's Code of Conduct] is a good reference in terms of
 behavior guidelines.
 
+> 🕮 Please also make sure to first familiarize yourself with the [`vanderschaarlab` Code of Conduct](https://github.com/vanderschaarlab/.github/blob/main/CODE_OF_CONDUCT.md).
+
 ## Issue Reports
 
 If you experience bugs or general issues with *TemporAI*, please have a look
@@ -70,7 +74,7 @@ python3 -m http.server --directory 'docs/_build/html'
 
 ## Code Contributions
 
-TBC: An architecture description, design principles or at least a summary of the main concepts.
+`TBC: Developer Guide`
 
 ### Submit an issue
 
@@ -113,7 +117,9 @@ conda activate temporai
 1. Run the following to install the package and all requirements, including dev requirements:
 
    ```sh
-   pip install -U pip -e .[dev]
+   pip install -U pip         # Update pip.
+   pip install -r prereq.txt  # Install prerequisite dependencies.
+   pip install -e .[dev]      # Install TemporAI in editable mode, with the `dev` extra.
    ```
 
 1. Install [pre-commit]:
@@ -123,8 +129,8 @@ conda activate temporai
    pre-commit install
    ```
 
-   *TemporAI* comes with a lot of hooks configured to automatically help the
-   developer to check the code being written.
+   *TemporAI* comes with a lot of [pre-commit hooks] configured to automatically help the developer to
+   check the code being written.
 
 ### Implement your changes
 
@@ -152,8 +158,9 @@ conda activate temporai
 
    Please make sure to see the validation messages from [pre-commit] and fix
    any eventual issues.
-   This should automatically use [flake8]/[black] to check/fix the code style
+   This should, among other things, automatically use [flake8]/[black] to check/fix the code style
    in a way that is compatible with the project.
+   See also the full list of the configured [pre-commit hooks].
 
    **Don't forget to add unit tests and documentation in case your
    contribution adds an additional feature and is not just a bugfix.**
@@ -166,24 +173,30 @@ conda activate temporai
    ```
 
    to look for recurring communication patterns.
-   :::
 
-1. Please check that your changes don't break any unit tests with:
+1. Please locally check that your changes don't break any tests. The same set of tests will be executed via [GitHub workflows] when you submit your PR.
 
    ```sh
-   # Run tests on different tox python environments:
-   tox -r
-   # Run doctests, similarly:
-   tox -r -- src/ --doctest-modules
-   # Run notebook tests:
-   tox -r -e testnb
+   # Run unit tests on your current environment.
+   pytest
+
+   # Run unit tests on different tox python environments (this may be slow).
+   # The tests will also include doctests, and a check that all notebooks execute without errors.
+   tox
+   # If your code introduces new dependencies, use `tox -r`.
    ```
 
-   (after having installed [tox] with `pip install tox` or `pipx`).
+   (after having installed [tox] with `pip install tox`).
 
    You can also use [tox] to run several other pre-configured tasks in the
    repository. Try `tox -av` to see a list of the available checks.
 
+1. It is also useful to check that documentation generation succeeds after your changes, run this with the following command, and make sure you do not see any [Sphinx] `WARNING`s or errors.
+   ```sh
+   tox -e docs
+   tox -e doctests
+   ```
+
 ### Submit your contribution
 
 1. Before submitting your contribution, make sure to read our [code of conduct].
@@ -259,29 +272,13 @@ package:
    running `tox -- -k <NAME OF THE FALLING TEST> --pdb`).
    You can also setup breakpoints manually instead of using the `--pdb` option.
 
-## Maintainer tasks
 
-### Releases
 
-> 	⚠️ This section is out of date, we now use [GitHub workflows] for releases.
+## Maintainer tasks
 
-If you are part of the group of maintainers and have correct user permissions
-on [PyPI], the following steps can be used to release a new version for
-*TemporAI*:
+### Releases
 
-1. Make sure all unit tests are successful.
-2. Tag the current commit on the main branch with a release tag, e.g., `v1.2.3`.
-3. Push the new tag to the upstream [repository],
-   e.g., `git push upstream v1.2.3`
-4. Clean up the `dist` and `build` folders with `tox -e clean`
-   (or `rm -rf dist build`)
-   to avoid confusion with old builds and Sphinx docs.
-5. Run `tox -e build` and check that the files in `dist` have
-   the correct version (no `.dirty` or [git] hash) according to the [git] tag.
-   Also check the sizes of the distributions, if they are too big (e.g., >
-   500KB), unwanted clutter may have been accidentally included.
-6. Run `tox -e publish -- --repository pypi` and check that everything was
-   uploaded to [PyPI] correctly.
+We now use [GitHub workflows] for releases, see [`release.yml`](https://github.com/vanderschaarlab/temporai/blob/main/.github/workflows/release.yml).
 
 
 
@@ -305,6 +302,7 @@ on [PyPI], the following steps can be used to release a new version for
 [PR template]: https://github.com/vanderschaarlab/.github/blob/main/.github/pull_request_template.md
 [other kinds of contributions]: https://opensource.guide/how-to-contribute
 [pre-commit]: https://pre-commit.com/
+[pre-commit hooks]: https://github.com/vanderschaarlab/temporai/blob/main//.pre-commit-config.yaml
 [pypi]: https://pypi.org/
 [PyScaffold contributor's guide template]: https://github.com/pyscaffold/pyscaffold/blob/835eb4f986e37409d33fdb3f4d150e41ee07a111/src/pyscaffold/templates/contributing.template
 [pyscaffold]: https://pyscaffold.org/
diff --git a/README.md b/README.md
index 639f85dc..30e7af82 100644
--- a/README.md
+++ b/README.md
@@ -3,35 +3,41 @@
 
 [![Built Status](https://api.cirrus-ci.com/github/<USER>/temporai.svg?branch=main)](https://cirrus-ci.com/github/<USER>/temporai)
 [![Coveralls](https://img.shields.io/coveralls/github/<USER>/temporai/main.svg)](https://coveralls.io/r/<USER>/temporai)
-[![PyPI-Server](https://img.shields.io/pypi/v/temporai.svg)](https://pypi.org/project/temporai/)
 [![Conda-Forge](https://img.shields.io/conda/vn/conda-forge/temporai.svg)](https://anaconda.org/conda-forge/temporai)
 [![Monthly Downloads](https://pepy.tech/badge/temporai/month)](https://pepy.tech/project/temporai)
 [![Twitter](https://img.shields.io/twitter/url/http/shields.io.svg?style=social&label=Twitter)](https://twitter.com/temporai)
 -->
 
 <!-- exclude_docs -->
-<!-- [![ReadTheDocs](https://readthedocs.org/projects/temporai/badge/?version=latest)][docs] -->
-[![Tests](https://github.com/vanderschaarlab/temporai/actions/workflows/test.yml/badge.svg)](https://github.com/vanderschaarlab/temporai/actions/workflows/test.yml)
-[![](https://pepy.tech/badge/temporai)](https://pypi.org/project/temporai/)
+[![Test In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/vanderschaarlab/temporai/blob/main/tutorials/user_guide/tutorial04_prediction.ipynb)
+[![Documentation Status](https://readthedocs.org/projects/temporai/badge/?version=latest)](https://temporai.readthedocs.io/en/latest/?badge=latest)
+
 [![Python 3.7+](https://img.shields.io/badge/python-3.7+-blue.svg)](https://www.python.org/downloads/release/python-370/)
-[![License](https://img.shields.io/github/license/vanderschaarlab/temporai)](./LICENSE.txt)
+[![PyPI-Server](https://img.shields.io/pypi/v/temporai.svg)](https://pypi.org/project/temporai/)
+[![](https://pepy.tech/badge/temporai)](https://pypi.org/project/temporai/)
+[![Tests](https://github.com/vanderschaarlab/temporai/actions/workflows/test.yml/badge.svg)](https://github.com/vanderschaarlab/temporai/actions/workflows/test.yml)
+[![Tests](https://github.com/vanderschaarlab/temporai/actions/workflows/test_full.yml/badge.svg)](https://github.com/vanderschaarlab/temporai/actions/workflows/test.yml)
+[![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](./LICENSE.txt)
+
+[![arXiv](https://img.shields.io/badge/arXiv-2301.12260-b31b1b.svg)](https://arxiv.org/abs/2301.12260)
 [![about](https://img.shields.io/badge/about-The%20van%20der%20Schaar%20Lab-blue)](https://www.vanderschaar-lab.com/)
 [![slack](https://img.shields.io/badge/chat-on%20slack-purple?logo=slack)](https://vanderschaarlab.slack.com)
-
 <!-- exclude_docs_end -->
 
 # <img src="docs/assets/TemporAI_Logo_Icon.png" height=25> TemporAI
 
-> **⚠️ Status**: **Work in progress, please come back at a later date.** We are migrating from a [previous iteration of the project](https://github.com/vanderschaarlab/clairvoyance).
+> **⚗️ Status:** This project is still in *alpha*, and the API may change without warning.  
 
-*TemporAI* is a Machine Learning-centric time-series library for medicine.  The tasks that are currently of focus in TemporAI are: time-series prediction, time-to-event (a.k.a. survival) analysis with time-series data, and counterfactual inference (i.e. \[individualized\] treatment effects).  The library also aims to provide the user with understanding of their data, model, and problem, through e.g. integration with interpretability methods.
+*TemporAI* is a Machine Learning-centric time-series library for medicine.  The tasks that are currently of focus in TemporAI are: time-series prediction, time-to-event (a.k.a. survival) analysis with time-series data, and counterfactual inference (i.e. \[individualized\] treatment effects).
+
+In future versions, the library also aims to provide the user with understanding of their data, model, and problem, through e.g. integration with interpretability methods.
 
 Key concepts:
 
 <div align="center">
 
 <!-- exclude_docs -->
-<img src="docs/assets/Conceptual.png" width="600" alt="key concepts">
+<img src="docs/assets/Conceptual.png" width="650" alt="key concepts">
 <!-- exclude_docs_end -->
 <!-- include_docs
 <img src="docs/assets/Conceptual.png" width="750" alt="key concepts">
@@ -63,19 +69,27 @@ from tempor.utils.dataloaders import SineDataLoader
 from tempor.plugins import plugin_loader
 
 dataset = SineDataLoader(with_missing=True).load()
-assert dataset.static.dataframe().isna().sum().sum() != 0
-assert dataset.time_series.dataframe().isna().sum().sum() != 0
+static_data_n_missing = dataset.static.dataframe().isna().sum().sum()
+temporal_data_n_missing = dataset.time_series.dataframe().isna().sum().sum()
+
+print(static_data_n_missing, temporal_data_n_missing)
+assert static_data_n_missing > 0
+assert temporal_data_n_missing > 0
 
-# load the model
+# Load the model:
 model = plugin_loader.get("preprocessing.imputation.temporal.bfill")
 
-# train
+# Train:
 model.fit(dataset)
 
-# impute
+# Impute:
 imputed = model.transform(dataset)
-assert imputed.static.dataframe().isna().sum().sum() == 0
-assert imputed.time_series.dataframe().isna().sum().sum() == 0
+static_data_n_missing = imputed.static.dataframe().isna().sum().sum()
+temporal_data_n_missing = imputed.time_series.dataframe().isna().sum().sum()
+
+print(static_data_n_missing, temporal_data_n_missing)
+assert static_data_n_missing == 0
+assert temporal_data_n_missing == 0
 ```
 
 * Use a classifier
@@ -85,14 +99,14 @@ from tempor.plugins import plugin_loader
 
 dataset = SineDataLoader().load()
 
-# load the model
+# Load the model:
 model = plugin_loader.get("prediction.one_off.classification.nn_classifier", n_iter=50)
 
-# train
+# Train:
 model.fit(dataset)
 
-# predict
-assert model.predict(dataset).numpy().shape == (len(dataset), 1)
+# Predict:
+prediction = model.predict(dataset)
 ```
 
 * Use a regressor
@@ -102,27 +116,23 @@ from tempor.plugins import plugin_loader
 
 dataset = SineDataLoader().load()
 
-# load the model
+# Load the model:
 model = plugin_loader.get("prediction.one_off.regression.nn_regressor", n_iter=50)
 
-# train
+# Train:
 model.fit(dataset)
 
-# predict
-assert model.predict(dataset).numpy().shape == (len(dataset), 1)
+# Predict:
+prediction = model.predict(dataset)
 ```
 
 * Benchmark models
 Classification task
 ```python
-from tempor.benchmarks import (
-    benchmark_models,
-)
+from tempor.benchmarks import benchmark_models
 from tempor.plugins import plugin_loader
 from tempor.plugins.pipeline import Pipeline
-from tempor.utils.dataloaders import (
-    SineDataLoader,
-)
+from tempor.utils.dataloaders import SineDataLoader
 
 testcases = [
     (
@@ -157,13 +167,13 @@ print(aggr_score)
 from tempor.utils.serialization import load, save
 from tempor.plugins import plugin_loader
 
-# load the model
+# Load the model:
 model = plugin_loader.get("prediction.one_off.classification.nn_classifier", n_iter=50)
 
-buff = save(model)  # save model to bytes
-reloaded = load(buff)  # reload model
+buff = save(model)  # Save model to bytes.
+reloaded = load(buff)  # Reload model.
 
-# save_to_file. load_from_file also available in the serialization module
+# `save_to_file`, `load_from_file` also available in the serialization module.
 ```
 
 ## 🔑 Methods
@@ -289,21 +299,33 @@ Treatment effects estimation where treatments are temporal (time series).
 
 
 
-## TemporAI Pipeline
-The diagram below illustrates the structure of a *TemporAI* pipeline:
+## Tutorials
+
+### Data
+
+- [![Test In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/vanderschaarlab/temporai/blob/main/tutorials/data/tutorial01_data_format.ipynb) - [Data Format](./tutorials/data/tutorial01_data_format.ipynb)
+- [![Test In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/vanderschaarlab/temporai/blob/main/tutorials/data/tutorial02_datasets.ipynb) - [Datasets](./tutorials/data/tutorial02_datasets.ipynb)
+- [![Test In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/vanderschaarlab/temporai/blob/main/tutorials/data/tutorial03_dataloaders.ipynb) - [Data Loaders](./tutorials/data/tutorial03_dataloaders.ipynb)
+
+### User Guide
+- [![Test In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/vanderschaarlab/temporai/blob/main/tutorials/user_guide/tutorial01_plugins.ipynb) - [Plugins](./tutorials/user_guide/tutorial01_plugins.ipynb)
+- [![Test In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/vanderschaarlab/temporai/blob/main/tutorials/user_guide/tutorial02_imputation.ipynb) - [Imputation](./tutorials/user_guide/tutorial02_imputation.ipynb)
+- [![Test In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/vanderschaarlab/temporai/blob/main/tutorials/user_guide/tutorial03_scaling.ipynb) - [Scaling](./tutorials/user_guide/tutorial03_scaling.ipynb)
+- [![Test In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/vanderschaarlab/temporai/blob/main/tutorials/user_guide/tutorial04_prediction.ipynb) - [Prediction](./tutorials/user_guide/tutorial04_prediction.ipynb)
+- [![Test In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/vanderschaarlab/temporai/blob/main/tutorials/user_guide/tutorial05_time_to_event.ipynb) - [Time-to-event Analysis](./tutorials/user_guide/tutorial05_time_to_event.ipynb)
+- [![Test In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/vanderschaarlab/temporai/blob/main/tutorials/user_guide/tutorial06_treatments.ipynb) - [Treatment Effects](./tutorials/user_guide/tutorial06_treatments.ipynb)
+- [![Test In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/vanderschaarlab/temporai/blob/main/tutorials/user_guide/tutorial07_pipeline.ipynb) - [Pipeline](./tutorials/user_guide/tutorial07_pipeline.ipynb)
+- [![Test In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/vanderschaarlab/temporai/blob/main/tutorials/user_guide/tutorial08_benchmarks.ipynb) - [Plugins](./tutorials/user_guide/tutorial08_benchmarks.ipynb)
+
+### Extending TemporAI
+- [![Test In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/vanderschaarlab/temporai/blob/main/tutorials/extending/tutorial01_custom_plugin.ipynb) - [Writing a Custom Plugin](./tutorials/extending/tutorial01_custom_plugin.ipynb)
 
-<img src="docs/assets/Pipeline.png" alt="pipeline diagram">
 
-<!--
-See [User Guide][docs/user_guide] for tutorials/examples.
--->
 
 <!-- exclude_docs -->
-<!--
-## Documentation
+## 📘 Documentation
 
-📖 See the project documentation [here](https://temporai.readthedocs.io/en/latest/).
--->
+See the project documentation [here](https://temporai.readthedocs.io/en/latest/).
 <!-- exclude_docs_end -->
 
 
@@ -330,5 +352,10 @@ pytest -vsx
 
 If you use this code, please cite the associated paper:
 ```
-TODO
+@article{saveliev2023temporai,
+  title={TemporAI: Facilitating Machine Learning Innovation in Time Domain Tasks for Medicine},
+  author={Saveliev, Evgeny S and van der Schaar, Mihaela},
+  journal={arXiv preprint arXiv:2301.12260},
+  year={2023}
+}
 ```
diff --git a/docs/assets/Conceptual.png b/docs/assets/Conceptual.png
index 280f4624..30fd69e6 100644
Binary files a/docs/assets/Conceptual.png and b/docs/assets/Conceptual.png differ
diff --git a/docs/index.md b/docs/index.md
index 1cda0862..69471c4a 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -16,6 +16,7 @@ TemporAI: ML-centric Toolkit for Medical Time Series
 :maxdepth: 3
 
 Overview <overview>
+User Guide <user_guide>
 Contributions & Help <contributing>
 License <license>
 Authors <authors>
diff --git a/docs/overview.md b/docs/overview.md
index f4246db8..f720cc5e 100644
--- a/docs/overview.md
+++ b/docs/overview.md
@@ -3,7 +3,6 @@
 
 [![Built Status](https://api.cirrus-ci.com/github/<USER>/temporai.svg?branch=main)](https://cirrus-ci.com/github/<USER>/temporai)
 [![Coveralls](https://img.shields.io/coveralls/github/<USER>/temporai/main.svg)](https://coveralls.io/r/<USER>/temporai)
-[![PyPI-Server](https://img.shields.io/pypi/v/temporai.svg)](https://pypi.org/project/temporai/)
 [![Conda-Forge](https://img.shields.io/conda/vn/conda-forge/temporai.svg)](https://anaconda.org/conda-forge/temporai)
 [![Monthly Downloads](https://pepy.tech/badge/temporai/month)](https://pepy.tech/project/temporai)
 [![Twitter](https://img.shields.io/twitter/url/http/shields.io.svg?style=social&label=Twitter)](https://twitter.com/temporai)
@@ -12,9 +11,11 @@
 
 # <img src="assets/TemporAI_Logo_Icon.png" height=25> TemporAI
 
-> **⚠️ Status**: **Work in progress, please come back at a later date.** We are migrating from a [previous iteration of the project](https://github.com/vanderschaarlab/clairvoyance).
+> **⚗️ Status:** This project is still in *alpha*, and the API may change without warning.  
 
-*TemporAI* is a Machine Learning-centric time-series library for medicine.  The tasks that are currently of focus in TemporAI are: time-series prediction, time-to-event (a.k.a. survival) analysis with time-series data, and counterfactual inference (i.e. \[individualized\] treatment effects).  The library also aims to provide the user with understanding of their data, model, and problem, through e.g. integration with interpretability methods.
+*TemporAI* is a Machine Learning-centric time-series library for medicine.  The tasks that are currently of focus in TemporAI are: time-series prediction, time-to-event (a.k.a. survival) analysis with time-series data, and counterfactual inference (i.e. \[individualized\] treatment effects).
+
+In future versions, the library also aims to provide the user with understanding of their data, model, and problem, through e.g. integration with interpretability methods.
 
 Key concepts:
 
@@ -38,92 +39,101 @@ $ pip install .
 
 ## 💥 Sample Usage
 * List the available plugins
-```python
+```{testcode}
+import os; import sys; f = open(os.devnull, 'w'); sys.stdout = f
 from tempor.plugins import plugin_loader
 
 print(plugin_loader.list())
 ```
 
 * Use an imputer
-```python
+```{testcode}
+import os; import sys; f = open(os.devnull, 'w'); sys.stdout = f
 from tempor.utils.dataloaders import SineDataLoader
 from tempor.plugins import plugin_loader
 
 dataset = SineDataLoader(with_missing=True).load()
-assert dataset.static.dataframe().isna().sum().sum() != 0
-assert dataset.time_series.dataframe().isna().sum().sum() != 0
+static_data_n_missing = dataset.static.dataframe().isna().sum().sum()
+temporal_data_n_missing = dataset.time_series.dataframe().isna().sum().sum()
+
+print(static_data_n_missing, temporal_data_n_missing)
+assert static_data_n_missing > 0
+assert temporal_data_n_missing > 0
 
-# load the model
-model = plugin_loader.get("preprocessing.imputation.bfill")
+# Load the model:
+model = plugin_loader.get("preprocessing.imputation.temporal.bfill")
 
-# train
+# Train:
 model.fit(dataset)
 
-# impute
+# Impute:
 imputed = model.transform(dataset)
-assert imputed.static.dataframe().isna().sum().sum() == 0
-assert imputed.time_series.dataframe().isna().sum().sum() == 0
+static_data_n_missing = imputed.static.dataframe().isna().sum().sum()
+temporal_data_n_missing = imputed.time_series.dataframe().isna().sum().sum()
+
+print(static_data_n_missing, temporal_data_n_missing)
+assert static_data_n_missing == 0
+assert temporal_data_n_missing == 0
 ```
 
 * Use a classifier
-```python
+```{testcode}
+import os; import sys; f = open(os.devnull, 'w'); sys.stdout = f
 from tempor.utils.dataloaders import SineDataLoader
 from tempor.plugins import plugin_loader
 
 dataset = SineDataLoader().load()
 
-# load the model
-model = plugin_loader.get("classification.nn_classifier", n_iter=50)
+# Load the model:
+model = plugin_loader.get("prediction.one_off.classification.nn_classifier", n_iter=50)
 
-# train
+# Train:
 model.fit(dataset)
 
-# predict
-assert model.predict(dataset).numpy().shape == (len(dataset), 1)
+# Predict:
+prediction = model.predict(dataset)
 ```
 
 * Use a regressor
-```python
+```{testcode}
+import os; import sys; f = open(os.devnull, 'w'); sys.stdout = f
 from tempor.utils.dataloaders import SineDataLoader
 from tempor.plugins import plugin_loader
 
 dataset = SineDataLoader().load()
 
-# load the model
-model = plugin_loader.get("regression.nn_regressor", n_iter=50)
+# Load the model:
+model = plugin_loader.get("prediction.one_off.regression.nn_regressor", n_iter=50)
 
-# train
+# Train:
 model.fit(dataset)
 
-# predict
-assert model.predict(dataset).numpy().shape == (len(dataset), 1)
+# Predict:
+prediction = model.predict(dataset)
 ```
 
 * Benchmark models
 Classification task
-```python
-from tempor.benchmarks import (
-    benchmark_models,
-)
+```{testcode}
+import os; import sys; f = open(os.devnull, 'w'); sys.stdout = f
+from tempor.benchmarks import benchmark_models
 from tempor.plugins import plugin_loader
 from tempor.plugins.pipeline import Pipeline
-from tempor.utils.dataloaders import (
-    SineDataLoader,
-)
+from tempor.utils.dataloaders import SineDataLoader
 
 testcases = [
     (
         "pipeline1",
         Pipeline(
             [
-                "preprocessing.scaling.static_minmax_scaler",
-                "classification.nn_classifier",
+                "preprocessing.scaling.static.static_minmax_scaler",
+                "prediction.one_off.classification.nn_classifier",
             ]
         )({"nn_classifier": {"n_iter": 10}}),
     ),
     (
         "plugin1",
-        plugin_loader.get("classification.nn_classifier", n_iter=10),
+        plugin_loader.get("prediction.one_off.classification.nn_classifier", n_iter=10),
     ),
 ]
 dataset = SineDataLoader().load()
@@ -139,44 +149,68 @@ aggr_score, per_test_score = benchmark_models(
 print(aggr_score)
 ```
 
-^ Serialization
-```python
+* Serialization
+```{testcode}
+import os; import sys; f = open(os.devnull, 'w'); sys.stdout = f
 from tempor.utils.serialization import load, save
 from tempor.plugins import plugin_loader
 
-# load the model
-model = plugin_loader.get("classification.nn_classifier", n_iter=50)
+# Load the model:
+model = plugin_loader.get("prediction.one_off.classification.nn_classifier", n_iter=50)
 
-buff = save(model)  # save model to bytes
-reloaded = load(buff)  # reload model
+buff = save(model)  # Save model to bytes.
+reloaded = load(buff)  # Reload model.
 
-# save_to_file. load_from_file also available in the serialization module
+# `save_to_file`, `load_from_file` also available in the serialization module.
 ```
 
 ## 🔑 Methods
 
+
+
 ### Prediction
-* Classification
+
+#### One-off
+Prediction where targets are static.
+
+* Classification (category: `prediction.one_off.classification`)
 
 | Name | Description| Reference |
 | --- | --- | --- |
-| `classification.nn_classifier` | Neural-net based classifier. Supports multiple recurrent models, like RNN, LSTM, Transformer etc.  | --- |
-| `classification.ode_classifier` | Classifier based on ordinary differential equation (ODE) solvers.  | --- |
-| `classification.cde_classifier` | Classifier based Neural Controlled Differential Equations for Irregular Time Series.  | [Paper](https://arxiv.org/abs/2005.08926) |
-| `classification.laplace_ode_classifier` | Classifier based Inverse Laplace Transform (ILT) algorithms implemented in PyTorch.  | [Paper](https://arxiv.org/abs/2206.04843) |
-| `classification.seq2seq_classifier` | Seq2Seq prediction  | --- |
+| `nn_classifier` | Neural-net based classifier. Supports multiple recurrent models, like RNN, LSTM, Transformer etc.  | --- |
+| `ode_classifier` | Classifier based on ordinary differential equation (ODE) solvers.  | --- |
+| `cde_classifier` | Classifier based Neural Controlled Differential Equations for Irregular Time Series.  | [Paper](https://arxiv.org/abs/2005.08926) |
+| `laplace_ode_classifier` | Classifier based Inverse Laplace Transform (ILT) algorithms implemented in PyTorch.  | [Paper](https://arxiv.org/abs/2206.04843) |
 
-* Regression
+* Regression (category: `prediction.one_off.regression`)
 
 | Name | Description| Reference |
 | --- | --- | --- |
-| `regression.nn_regressor` | Neural-net based regressor. Supports multiple recurrent models, like RNN, LSTM, Transformer etc.  | --- |
-| `regression.ode_regressor` | Regressor based on ordinary differential equation (ODE) solvers.  | --- |
-| `regression.cde_regressor` | Regressor based Neural Controlled Differential Equations for Irregular Time Series.  | [Paper](https://arxiv.org/abs/2005.08926)
-| `regression.laplace_ode_regressor` | Regressor based Inverse Laplace Transform (ILT) algorithms implemented in PyTorch.  | [Paper](https://arxiv.org/abs/2206.04843) |
-| `classification.seq2seq_regressor` | Seq2Seq prediction  | --- |
+| `nn_regressor` | Neural-net based regressor. Supports multiple recurrent models, like RNN, LSTM, Transformer etc.  | --- |
+| `ode_regressor` | Regressor based on ordinary differential equation (ODE) solvers.  | --- |
+| `cde_regressor` | Regressor based Neural Controlled Differential Equations for Irregular Time Series.  | [Paper](https://arxiv.org/abs/2005.08926)
+| `laplace_ode_regressor` | Regressor based Inverse Laplace Transform (ILT) algorithms implemented in PyTorch.  | [Paper](https://arxiv.org/abs/2206.04843) |
+
+#### Temporal
+Prediction where targets are temporal (time series).
 
-* Time-to-Event
+* Classification (category: `prediction.temporal.classification`)
+
+| Name | Description| Reference |
+| --- | --- | --- |
+| `seq2seq_classifier` | Seq2Seq prediction, classification | --- |
+
+* Regression (category: `prediction.temporal.regression`)
+
+| Name | Description| Reference |
+| --- | --- | --- |
+| `seq2seq_regressor` | Seq2Seq prediction, regression | --- |
+
+
+
+### Time-to-Event
+
+Risk estimation given event data (category: `time_to_event`)
 
 | Name | Description| Reference |
 | --- | --- | --- |
@@ -184,91 +218,97 @@ reloaded = load(buff)  # reload model
 | `ts_coxph` | Create embeddings from the time series and use a CoxPH model for predicting the survival function| --- |
 | `ts_xgb` | Create embeddings from the time series and use a SurvivalXGBoost model for predicting the survival function| --- |
 
-* Treatment effects
+
+
+### Treatment effects
+
+#### One-off
+Treatment effects estimation where treatments are a one-off event.
+
+<!--
+* Classification on the outcomes (category: `treatments.one_off.classification`)
+-->
+
+* Regression on the outcomes (category: `treatments.one_off.regression`)
 
 | Name | Description| Reference |
 | --- | --- | --- |
-| `crn_regressor` | The Counterfactual Recurrent Network (CRN), a sequence-to-sequence model that leverages the available patient observational data to estimate treatment effects over time. | [Paper](https://arxiv.org/abs/2002.04083) |
-| `crn_classifier` | The Counterfactual Recurrent Network (CRN), a sequence-to-sequence model that leverages the available patient observational data to estimate treatment effects over time. | [Paper](https://arxiv.org/abs/2002.04083) |
 | `synctwin_regressor` | SyncTwin is a treatment effect estimation method tailored for observational studies with longitudinal data, applied to the LIP setting: Longitudinal, Irregular and Point treatment.  | [Paper](https://proceedings.neurips.cc/paper/2021/hash/19485224d128528da1602ca47383f078-Abstract.html) |
 
+#### Temporal
+Treatment effects estimation where treatments are temporal (time series).
 
-
-### Preprocessing
-* Imputation
+* Classification on the outcomes (category: `treatments.temporal.classification`)
 
 | Name | Description| Reference |
 | --- | --- | --- |
-| `preprocessing.imputation.ffill` | Propagate last valid observation forward to next valid  | --- |
-| `preprocessing.imputation.bfill` | Use next valid observation to fill gap | --- |
-| `preprocessing.imputation.static_imputation` | Use HyperImpute to impute both the static and temporal data | [Paper](https://arxiv.org/abs/2206.07769) |
+| `crn_classifier` | The Counterfactual Recurrent Network (CRN), a sequence-to-sequence model that leverages the available patient observational data to estimate treatment effects over time. | [Paper](https://arxiv.org/abs/2002.04083) |
 
-* Scalers
+* Regression on the outcomes (category: `treatments.temporal.regression`)
 
 | Name | Description| Reference |
 | --- | --- | --- |
-| `preprocessing.scaling.static_standard_scaler` | Scale the static features using a StandardScaler | --- |
-| `preprocessing.scaling.static_minmax_scaler` | Scale the static features using a MinMaxScaler | --- |
-| `preprocessing.scaling.ts_standard_scaler` | Scale the temporal features using a StandardScaler | --- |
-| `preprocessing.scaling.ts_minmax_scaler` | Scale the temporal features using a MinMaxScaler | --- |
+| `crn_regressor` | The Counterfactual Recurrent Network (CRN), a sequence-to-sequence model that leverages the available patient observational data to estimate treatment effects over time. | [Paper](https://arxiv.org/abs/2002.04083) |
 
-<!--
-## Models
 
-**Time Series Prediction (Forecasting)**
 
-| Model &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | Affiliation &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; | Paper | Status &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; |
-| ----- | ----------- | ----- | ------ |
-| A version of LSTM | Classic method | [📄](https://ieeexplore.ieee.org/abstract/document/6795963) | ✔️ Available |
-| A version of GRU | Classic method | [📄](https://arxiv.org/abs/1409.1259) | ✔️ Available |
-| A version of Seq2Seq | Classic method | [📄](https://proceedings.neurips.cc/paper/2014/hash/a14ac55a4f27472c5d894ec1c3c743d2-Abstract.html) | ✔️ Available |
-| [NeuralLaplace](https://github.com/samholt/NeuralLaplace) | [van der Schaar Lab] | [📄](https://proceedings.mlr.press/v162/holt22a.html) | 🔵 Planned |
+### Preprocessing
+
+#### Imputation
+
+* Static data (category: `preprocessing.imputation.static`)
+
+| Name | Description| Reference |
+| --- | --- | --- |
+| `static_imputation` | Use HyperImpute to impute both the static and temporal data | [Paper](https://arxiv.org/abs/2206.07769) |
 
-**Time Series Imputation**
+* Temporal data (category: `preprocessing.imputation.temporal`)
 
-| Model &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | Affiliation &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; | Paper | Status &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; |
-| ----- | ----------- | ----- | ------ |
-| `{f,b}fill` & Mean | Classic method(s) | N/A | ✔️ Available |
-| [HyperImpute](https://github.com/vanderschaarlab/HyperImpute) | [van der Schaar Lab] | [📄](https://proceedings.mlr.press/v162/jarrett22a/jarrett22a.pdf) | 🔵 Planned
+| Name | Description| Reference |
+| --- | --- | --- |
+| `ffill` | Propagate last valid observation forward to next valid  | --- |
+| `bfill` | Use next valid observation to fill gap | --- |
 
-**Temporal Treatment Effects**
+### Scaling
 
-| Model &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | Affiliation &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; | Paper | Status &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; |
-| ----- | ----------- | ----- | ------ |
-| [CRN](https://github.com/vanderschaarlab/mlforhealthlabpub/tree/main/alg/counterfactual_recurrent_network) | [van der Schaar Lab] | [📄](https://openreview.net/forum?id=BJg866NFvB) | ✔️ Available |
-| [SyncTwin](https://github.com/vanderschaarlab/SyncTwin-NeurIPS-2021/) | [van der Schaar Lab] | [📄](https://proceedings.neurips.cc/paper/2021/hash/19485224d128528da1602ca47383f078-Abstract.html) | ➰ Experimental |
-| [TE-CDE](https://github.com/vanderschaarlab/TE-CDE/) | [van der Schaar Lab] | [📄](https://proceedings.mlr.press/v162/seedat22b/seedat22b.pdf) | 🔵 Planned |
+* Static data (category: `preprocessing.scaling.static`)
 
-**Temporal Time-to-event Analysis**
+| Name | Description| Reference |
+| --- | --- | --- |
+| `static_standard_scaler` | Scale the static features using a StandardScaler | --- |
+| `static_minmax_scaler` | Scale the static features using a MinMaxScaler | --- |
 
-| Model &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | Affiliation &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; | Paper | Status &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; |
-| ----- | ----------- | ----- | ------ |
-| [Dynamic DeepHit Lite](https://github.com/chl8856/prostate_temporal) | [van der Schaar Lab] | [📄](https://www.nature.com/articles/s41746-022-00659-w) | ➰ Experimental |
-| [Dynamic DeepHit](https://github.com/vanderschaarlab/mlforhealthlabpub/tree/main/alg/dynamic_deephit) | [van der Schaar Lab] | [📄](https://pubmed.ncbi.nlm.nih.gov/30951460/) | 🔵 Planned |
+* Temporal data (category: `preprocessing.scaling.temporal`)
 
-**Interpretability**
+| Name | Description| Reference |
+| --- | --- | --- |
+| `ts_standard_scaler` | Scale the temporal features using a StandardScaler | --- |
+| `ts_minmax_scaler` | Scale the temporal features using a MinMaxScaler | --- |
 
-| Model &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | Affiliation &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; | Paper | Status &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; |
-| ----- | ----------- | ----- | ------ |
-| [DynaMask](https://github.com/vanderschaarlab/Dynamask) | [van der Schaar Lab] | [📄](https://proceedings.mlr.press/v139/crabbe21a.html) | 🔵 Planned |
 
-**Temporal Clustering**
 
-| Model &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | Affiliation &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; | Paper | Status &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; |
-| ----- | ----------- | ----- | ------ |
-| [AC-TPC](https://github.com/vanderschaarlab/mlforhealthlabpub/tree/main/alg/ac_tpc) | [van der Schaar Lab] | [📄](https://proceedings.mlr.press/v119/lee20h.html) | 🔵 Planned |
+## Tutorials
 
-\* `✔️ Available` & `➰ Experimental` may include some items still to be migrated from the [previous iteration of the project](https://github.com/vanderschaarlab/clairvoyance2).
--->
+### Data
 
-## TemporAI Pipeline
-The diagram below illustrates the structure of a *TemporAI* pipeline:
+- [![Test In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/vanderschaarlab/temporai/blob/main/tutorials/data/tutorial01_data_format.ipynb) - [Data Format](https://github.com/vanderschaarlab/temporai/tutorials/data/tutorial01_data_format.ipynb)
+- [![Test In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/vanderschaarlab/temporai/blob/main/tutorials/data/tutorial02_datasets.ipynb) - [Datasets](https://github.com/vanderschaarlab/temporai/tutorials/data/tutorial02_datasets.ipynb)
+- [![Test In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/vanderschaarlab/temporai/blob/main/tutorials/data/tutorial03_dataloaders.ipynb) - [Data Loaders](https://github.com/vanderschaarlab/temporai/tutorials/data/tutorial03_dataloaders.ipynb)
+
+### User Guide
+- [![Test In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/vanderschaarlab/temporai/blob/main/tutorials/user_guide/tutorial01_plugins.ipynb) - [Plugins](https://github.com/vanderschaarlab/temporai/tutorials/user_guide/tutorial01_plugins.ipynb)
+- [![Test In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/vanderschaarlab/temporai/blob/main/tutorials/user_guide/tutorial02_imputation.ipynb) - [Imputation](https://github.com/vanderschaarlab/temporai/tutorials/user_guide/tutorial02_imputation.ipynb)
+- [![Test In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/vanderschaarlab/temporai/blob/main/tutorials/user_guide/tutorial03_scaling.ipynb) - [Scaling](https://github.com/vanderschaarlab/temporai/tutorials/user_guide/tutorial03_scaling.ipynb)
+- [![Test In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/vanderschaarlab/temporai/blob/main/tutorials/user_guide/tutorial04_prediction.ipynb) - [Prediction](https://github.com/vanderschaarlab/temporai/tutorials/user_guide/tutorial04_prediction.ipynb)
+- [![Test In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/vanderschaarlab/temporai/blob/main/tutorials/user_guide/tutorial05_time_to_event.ipynb) - [Time-to-event Analysis](https://github.com/vanderschaarlab/temporai/tutorials/user_guide/tutorial05_time_to_event.ipynb)
+- [![Test In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/vanderschaarlab/temporai/blob/main/tutorials/user_guide/tutorial06_treatments.ipynb) - [Treatment Effects](https://github.com/vanderschaarlab/temporai/tutorials/user_guide/tutorial06_treatments.ipynb)
+- [![Test In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/vanderschaarlab/temporai/blob/main/tutorials/user_guide/tutorial07_pipeline.ipynb) - [Pipeline](https://github.com/vanderschaarlab/temporai/tutorials/user_guide/tutorial07_pipeline.ipynb)
+- [![Test In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/vanderschaarlab/temporai/blob/main/tutorials/user_guide/tutorial08_benchmarks.ipynb) - [Plugins](https://github.com/vanderschaarlab/temporai/tutorials/user_guide/tutorial08_benchmarks.ipynb)
+
+### Extending TemporAI
+- [![Test In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/vanderschaarlab/temporai/blob/main/tutorials/extending/tutorial01_custom_plugin.ipynb) - [Writing a Custom Plugin](https://github.com/vanderschaarlab/temporai/tutorials/extending/tutorial01_custom_plugin.ipynb)
 
-<img src="assets/Pipeline.png" alt="pipeline diagram">
 
-<!--
-See [User Guide](user_guide/index) for tutorials/examples.
--->
 
 
 
@@ -292,5 +332,10 @@ pytest -vsx
 
 If you use this code, please cite the associated paper:
 ```
-TODO
+@article{saveliev2023temporai,
+  title={TemporAI: Facilitating Machine Learning Innovation in Time Domain Tasks for Medicine},
+  author={Saveliev, Evgeny S and van der Schaar, Mihaela},
+  journal={arXiv preprint arXiv:2301.12260},
+  year={2023}
+}
 ```
diff --git a/docs/pre_build.py b/docs/pre_build.py
index 3e018efb..baff7384 100644
--- a/docs/pre_build.py
+++ b/docs/pre_build.py
@@ -16,7 +16,7 @@
     docs_req_content = file.read()
 found = re.findall(r"# ----- auto_update -----.*# ----- auto_update -----", docs_req_content, re.DOTALL)[0]
 new = "# ----- auto_update -----\n" + "\n".join(sorted(list_dep_specs)) + "\n# ----- auto_update -----"
-docs_req_content = docs_req_content.replace(found, new)
+docs_req_content = docs_req_content.replace(found, new)  # type: ignore
 
 with open(DOCS_REQS_FILE, "w", encoding="utf8") as file:
     file.write(docs_req_content)
@@ -40,10 +40,20 @@
 # Replace:
 for k, v in REPLACE.items():
     readme_content = readme_content.replace(k, v)
+
 # Remove parts that should only be in repo `README.md`.
 readme_content = re.sub(r"\n<!-- exclude_docs -->.*?<!-- exclude_docs_end -->", "", readme_content, flags=re.DOTALL)
+
+# Make ```python ... ``` into doctest blocks. Redirect output to devnull in order to skip output checking here.
+readme_content = re.sub(
+    r"```python(.*?)```",
+    r"```{testcode}\nimport os; import sys; f = open(os.devnull, 'w'); sys.stdout = f\1```",
+    readme_content,
+    flags=re.DOTALL,
+)
+
 # Make emoji representations compatible with sphinxemoji, e.g. :key: --> |:key:|
-readme_content = re.sub(r"\:[a-z1-9+\-_]{0,100}\:", (lambda x: f"|{x.group(0)}|"), readme_content)
+# readme_content = re.sub(r"\:[a-z1-9+\-_]{0,100}\:", (lambda x: f"|{x.group(0)}|"), readme_content)
 
 with open(OVERVIEW_PATH, "w", encoding="utf8") as file:
     file.write(readme_content)
diff --git a/docs/requirements.txt b/docs/requirements.txt
index 6f77b855..872a3e34 100644
--- a/docs/requirements.txt
+++ b/docs/requirements.txt
@@ -1,7 +1,7 @@
 # To build the module reference correctly, make sure every external package
 # under `install_requires` in `setup.cfg` is also listed here!
 # ----- auto_update -----
-clairvoyance2
+clairvoyance2 >=0.0.2
 cloudpickle
 hydra-core >=1.3
 hyperimpute >= 0.1.17
@@ -9,6 +9,7 @@ importlib-metadata; python_version<"3.8"
 lifelines
 loguru
 numpy >=1
+packaging
 pandas >=1
 pandera >=0.13
 pydantic >=1, <2
diff --git a/docs/user_guide.md b/docs/user_guide.md
new file mode 100644
index 00000000..dd8b8215
--- /dev/null
+++ b/docs/user_guide.md
@@ -0,0 +1,63 @@
+# User Guide
+
+We provide a user guide in the form of a series of notebooks.
+
+
+
+## Data Tutorials
+
+**Data Format:**
+
+[![Test In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/vanderschaarlab/temporai/blob/main/tutorials/data/tutorial01_data_format.ipynb)
+
+**Datasets:**
+
+[![Test In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/vanderschaarlab/temporai/blob/main/tutorials/data/tutorial02_datasets.ipynb)
+
+**Data Loaders:**
+
+[![Test In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/vanderschaarlab/temporai/blob/main/tutorials/data/tutorial03_dataloaders.ipynb)
+
+
+
+## Main Tutorials
+
+**Plugins:**
+
+[![Test In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/vanderschaarlab/temporai/blob/main/tutorials/user_guide/tutorial01_plugins.ipynb)
+
+**Imputation:**
+
+[![Test In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/vanderschaarlab/temporai/blob/main/tutorials/user_guide/tutorial02_imputation.ipynb)
+
+**Scaling:**
+
+[![Test In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/vanderschaarlab/temporai/blob/main/tutorials/user_guide/tutorial03_scaling.ipynb)
+
+**Prediction:**
+
+[![Test In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/vanderschaarlab/temporai/blob/main/tutorials/user_guide/tutorial04_prediction.ipynb)
+
+**Time:**
+
+[![Test In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/vanderschaarlab/temporai/blob/main/tutorials/user_guide/tutorial05_time_to_event.ipynb)
+
+**Treatment:**
+
+[![Test In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/vanderschaarlab/temporai/blob/main/tutorials/user_guide/tutorial06_treatments.ipynb)
+
+**Pipeline:**
+
+[![Test In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/vanderschaarlab/temporai/blob/main/tutorials/user_guide/tutorial07_pipeline.ipynb)
+
+**Plugins:**
+
+[![Test In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/vanderschaarlab/temporai/blob/main/tutorials/user_guide/tutorial08_benchmarks.ipynb)
+
+
+
+## Extending the Library
+
+**Writing a Custom Plugin:**
+
+[![Test In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/vanderschaarlab/temporai/blob/main/tutorials/extending/tutorial01_custom_plugin.ipynb)
diff --git a/docs/user_guide/basic_usage.md b/docs/user_guide/basic_usage.md
deleted file mode 100644
index 36ff143e..00000000
--- a/docs/user_guide/basic_usage.md
+++ /dev/null
@@ -1,5 +0,0 @@
-# Basic Usage
-
-> 💡 We are in process of migrating the modules from the [previous iteration of the project](https://github.com/vanderschaarlab/clairvoyance2).
-
-📓 See example notebook [here](https://github.com/vanderschaarlab/clairvoyance2/blob/main/tutorials/basic_usage.ipynb).
diff --git a/docs/user_guide/index.md b/docs/user_guide/index.md
deleted file mode 100644
index f708a85a..00000000
--- a/docs/user_guide/index.md
+++ /dev/null
@@ -1,8 +0,0 @@
-# User guide
-
-```{toctree}
-:glob:
-:maxdepth: 2
-
-*
-```
diff --git a/docs/user_guide/survival_analysis.md b/docs/user_guide/survival_analysis.md
deleted file mode 100644
index 4764da41..00000000
--- a/docs/user_guide/survival_analysis.md
+++ /dev/null
@@ -1,5 +0,0 @@
-# Time-to-event Analysis
-
-> 💡 We are in process of migrating the modules from the [previous iteration of the project](https://github.com/vanderschaarlab/clairvoyance2).
-
-🚧 Coming soon.
diff --git a/docs/user_guide/treatment_effects.md b/docs/user_guide/treatment_effects.md
deleted file mode 100644
index 878b8ac1..00000000
--- a/docs/user_guide/treatment_effects.md
+++ /dev/null
@@ -1,7 +0,0 @@
-# Treatment Effects
-
-> 💡 We are in process of migrating the modules from the [previous iteration of the project](https://github.com/vanderschaarlab/clairvoyance2).
-
-📓 See example notebook using CRN [here](https://github.com/vanderschaarlab/clairvoyance2/blob/main/tutorials/crn.ipynb).
-
-📓 See example notebook using SyncTwin [here](https://github.com/vanderschaarlab/clairvoyance2/blob/main/tutorials/synctwin.ipynb)
diff --git a/pyproject.toml b/pyproject.toml
index 3c14978c..0d6df8b8 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -11,7 +11,7 @@ version_scheme = "no-guess-dev"
 [tool.black]
 line-length = 120
 target-version = ['py37', 'py38', 'py39', 'py310']
-include = '\.pyi?$'
+include = '\.(pyi?|ipynb)$'
 # extend-exclude = '''
 # ^/(
 #     docs/conf.py
diff --git a/src/tempor/data/dataset.py b/src/tempor/data/dataset.py
index 5dd8c34a..43717118 100644
--- a/src/tempor/data/dataset.py
+++ b/src/tempor/data/dataset.py
@@ -305,7 +305,7 @@ def __init__(
     @property
     @abc.abstractmethod
     def predict_ready(self) -> bool:  # pragma: no cover
-        """Returns whether the :class:`PredictiveDataset` is in a state ready to be ``predict``ed on."""
+        """Returns whether the :class:`PredictiveDataset` is in a state ready to be ``predict`` ed on."""
         ...
 
 
diff --git a/src/tempor/data/samples.py b/src/tempor/data/samples.py
index 522b722d..1875fed2 100644
--- a/src/tempor/data/samples.py
+++ b/src/tempor/data/samples.py
@@ -39,6 +39,14 @@ def __init__(
     def __repr__(self) -> str:
         return f"{self.__class__.__name__} with data:\n{self.dataframe()}"
 
+    def _repr_html_(self) -> str:
+        repr_ = (
+            # pylint: disable-next=protected-access
+            f'<p><span style="font-family: monospace;">{self.__class__.__name__}</span> with data:</p>'
+            f"{self.dataframe()._repr_html_()}"  # pyright: ignore
+        )
+        return repr_
+
     def validate(self) -> None:
         with log_helpers.exc_to_log():
             try:
diff --git a/src/tempor/data/utils.py b/src/tempor/data/utils.py
index 77e490eb..f8032c44 100644
--- a/src/tempor/data/utils.py
+++ b/src/tempor/data/utils.py
@@ -95,6 +95,8 @@ def check_bool_array1d_trues_consecutive(array: np.ndarray, at_beginning: bool =
 
     Examples:
         >>> import numpy as np
+        >>> from tempor.data.utils import *
+        >>>
         >>> check_bool_array1d_trues_consecutive(np.asarray([False, True, True, True, False]))
         True
         >>> check_bool_array1d_trues_consecutive(np.asarray([False, True, False, True, False]))
@@ -127,6 +129,8 @@ def check_bool_array2d_identical_along_dim1(array: np.ndarray) -> bool:
 
     Examples:
         >>> import numpy as np
+        >>> from tempor.data.utils import *
+        >>>
         >>> check_bool_array2d_identical_along_dim1(np.asarray([[True, True, False], [True, True, False]]).T)
         True
         >>> check_bool_array2d_identical_along_dim1(np.asarray([[True, True, False], [False, True, False]]).T)
@@ -145,6 +149,8 @@ def get_array1d_length_until_padding(array: np.ndarray, padding_indicator: Any =
 
     Examples:
         >>> import numpy as np
+        >>> from tempor.data.utils import *
+        >>>
         >>> pad = 999.0
         >>> get_array1d_length_until_padding(np.asarray([1, 8, -3, 9, pad]), padding_indicator=pad)
         4
@@ -183,6 +189,8 @@ def get_seq_lengths_timeseries_array3d(array: np.ndarray, padding_indicator: Any
 
     Example:
         >>> import numpy as np
+        >>> from tempor.data.utils import *
+        >>>
         >>> pad = 999.0
         >>> array = np.asarray(  # Array with two samples, with two timeseries features.
         ...     [
@@ -247,6 +255,8 @@ def make_sample_time_index_tuples(
     ``[(<sample ID>, <timestep>), ...]``.
 
     Example:
+        >>> from tempor.data.utils import *
+        >>>
         >>> sample_index = ["s1", "s2"]
         >>> time_indexes = [[1, 2, 3], [1, 5, 9, 10]]
         >>> make_sample_time_index_tuples(sample_index, time_indexes)
@@ -389,6 +399,8 @@ def event_time_value_pairs_to_event_dataframe(
             List of feature names, to be set as dataframe column names.
 
     Example:
+        >>> from tempor.data.utils import *
+        >>>
         >>> sample_index = ["s1", "s2", "s3"]
         >>> feature_names = ["feature_1", "feature_2"]
         >>> event_feature_1 = ([1.1, 1.2, 1.3], [True, True, False])
diff --git a/src/tempor/plugins/core/_plugin.py b/src/tempor/plugins/core/_plugin.py
index 14cc348a..4c101eeb 100644
--- a/src/tempor/plugins/core/_plugin.py
+++ b/src/tempor/plugins/core/_plugin.py
@@ -139,6 +139,10 @@ def list_classes(self) -> Dict:
         self._refresh()
         return self._plugin_class_by_category
 
+    def list_categories(self) -> Dict[str, Type[Plugin]]:
+        self._refresh()
+        return PLUGIN_CATEGORY_REGISTRY
+
     def _raise_plugin_does_not_exist_error(self, name: str):
         if name not in self._plugin_registry:
             raise ValueError(f"Plugin {name} does not exist.")
diff --git a/src/tempor/utils/dataloaders/__init__.py b/src/tempor/utils/dataloaders/__init__.py
index e55f4ff3..8063c7ac 100644
--- a/src/tempor/utils/dataloaders/__init__.py
+++ b/src/tempor/utils/dataloaders/__init__.py
@@ -7,11 +7,13 @@
 from .pkpd import PKPDDataLoader
 from .sine import SineDataLoader
 
-__all__ = [
-    "DummyTemporalPredictionDataLoader",
-    "DummyTemporalTreatmentEffectsDataLoader",
-    "GoogleStocksDataLoader",
-    "PBCDataLoader",
-    "PKPDDataLoader",
-    "SineDataLoader",
+all_dataloaders = [
+    DummyTemporalPredictionDataLoader,
+    DummyTemporalTreatmentEffectsDataLoader,
+    GoogleStocksDataLoader,
+    PBCDataLoader,
+    PKPDDataLoader,
+    SineDataLoader,
 ]
+
+__all__ = [x.__name__ for x in all_dataloaders]  # pyright: ignore
diff --git a/tutorials/data/tutorial01_data_format.ipynb b/tutorials/data/tutorial01_data_format.ipynb
new file mode 100644
index 00000000..99d24331
--- /dev/null
+++ b/tutorials/data/tutorial01_data_format.ipynb
@@ -0,0 +1,1245 @@
+{
+ "cells": [
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Data Tutorial 01: Data Format\n",
+    "\n",
+    "This tutorial shows a minimal example of the data format for TemporAI."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "*Skip the below cell if you are not on Google Colab / already have TemporAI installed:*"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "%pip install temporai\n",
+    "\n",
+    "# Or from the repo, for the latest version:\n",
+    "# %pip install git+https://github.com/vanderschaarlab/temporai.git"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Time series data\n",
+    "\n",
+    "Time series data contains data samples (e.g. patients), with features that unfold sequentially over some number of timesteps.\n",
+    "\n",
+    "Time series data should take form of a `pandas.DataFrame`, with the following specifics:\n",
+    "* The index should be a 2-level multiindex, where level `0` index represents sampled IDs, and level `1` represents the timesteps for each sample.\n",
+    "* The sample index can be comprised of either `int`s or `str`s (homogenous, not a mix of these).\n",
+    "* The time index (timesteps) may be `int`, `float` or `pandas.Timestep`-compatible format (homogenous, not a mix of these).\n",
+    "* The columns of the dataframe represent the features, column names must be `str`.\n",
+    "* Column (feature) values currently supported are: `bool`, `int`, `float`, or `pandas.Categorical` (homogenous per column).\n",
+    "\n",
+    "Other points to note:\n",
+    "* Sample IDs must be unique.\n",
+    "* (Sample ID, timestep) combination must be unique (a sample cannot have more than one of the same timestep).\n",
+    "* Null values such as `numpy.nan` are allowed and represent missing values."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 18,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import pandas as pd\n",
+    "import numpy as np\n",
+    "\n",
+    "from IPython.display import display"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "<class 'pandas.core.frame.DataFrame'>\n",
+      "MultiIndex: 7 entries, ('sample_0', 1) to ('sample_2', 9)\n",
+      "Data columns (total 3 columns):\n",
+      " #   Column    Non-Null Count  Dtype   \n",
+      "---  ------    --------------  -----   \n",
+      " 0   t_feat_0  7 non-null      int64   \n",
+      " 1   t_feat_1  6 non-null      float64 \n",
+      " 2   t_feat_2  7 non-null      category\n",
+      "dtypes: category(1), float64(1), int64(1)\n",
+      "memory usage: 725.0+ bytes\n"
+     ]
+    },
+    {
+     "data": {
+      "text/html": [
+       "<div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th>t_feat_0</th>\n",
+       "      <th>t_feat_1</th>\n",
+       "      <th>t_feat_2</th>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_idx</th>\n",
+       "      <th>time_idx</th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"4\" valign=\"top\">sample_0</th>\n",
+       "      <th>1</th>\n",
+       "      <td>11</td>\n",
+       "      <td>1.1</td>\n",
+       "      <td>a</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>2</th>\n",
+       "      <td>12</td>\n",
+       "      <td>1.2</td>\n",
+       "      <td>b</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>3</th>\n",
+       "      <td>13</td>\n",
+       "      <td>1.3</td>\n",
+       "      <td>b</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>14</td>\n",
+       "      <td>NaN</td>\n",
+       "      <td>c</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"2\" valign=\"top\">sample_1</th>\n",
+       "      <th>2</th>\n",
+       "      <td>21</td>\n",
+       "      <td>2.1</td>\n",
+       "      <td>a</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>22</td>\n",
+       "      <td>2.2</td>\n",
+       "      <td>a</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_2</th>\n",
+       "      <th>9</th>\n",
+       "      <td>31</td>\n",
+       "      <td>3.1</td>\n",
+       "      <td>c</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "                     t_feat_0  t_feat_1 t_feat_2\n",
+       "sample_idx time_idx                             \n",
+       "sample_0   1               11       1.1        a\n",
+       "           2               12       1.2        b\n",
+       "           3               13       1.3        b\n",
+       "           4               14       NaN        c\n",
+       "sample_1   2               21       2.1        a\n",
+       "           4               22       2.2        a\n",
+       "sample_2   9               31       3.1        c"
+      ]
+     },
+     "execution_count": 3,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# Create a time series dataframe.\n",
+    "\n",
+    "time_series_df = pd.DataFrame(\n",
+    "    {\n",
+    "        \"sample_idx\": [\"sample_0\", \"sample_0\", \"sample_0\", \"sample_0\", \"sample_1\", \"sample_1\", \"sample_2\"],\n",
+    "        \"time_idx\": [1, 2, 3, 4, 2, 4, 9],\n",
+    "        \"t_feat_0\": [11, 12, 13, 14, 21, 22, 31],\n",
+    "        \"t_feat_1\": [1.1, 1.2, 1.3, np.nan, 2.1, 2.2, 3.1],\n",
+    "        \"t_feat_2\": [\"a\", \"b\", \"b\", \"c\", \"a\", \"a\", \"c\"],\n",
+    "    }\n",
+    ")\n",
+    "\n",
+    "# Set the 2-level index:\n",
+    "time_series_df.set_index(keys=[\"sample_idx\", \"time_idx\"], drop=True, inplace=True)\n",
+    "\n",
+    "# \"feat_2\" needs to be set to a categorical, as `str` format is not supported.\n",
+    "time_series_df[\"t_feat_2\"] = pd.Categorical(time_series_df[\"t_feat_2\"])\n",
+    "\n",
+    "# Preview the dataframe:\n",
+    "time_series_df.info()\n",
+    "time_series_df"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Static data\n",
+    "\n",
+    "Static data contains data samples (e.g. patients), features that are not associated with a particular time.\n",
+    "\n",
+    "Static data should take form of a `pandas.DataFrame`, with the following specifics:\n",
+    "* The index represents sample IDs and is a (single level) index that can be comprised of `int`s or `str`s (homogenous, not a mix of these).\n",
+    "* The columns of the dataframe represent the features, column names must be `str`.\n",
+    "* Column (feature) values currently supported are: `bool`, `int`, `float`, or `pandas.Categorical` (homogenous per column).\n",
+    "\n",
+    "Other points to note:\n",
+    "* Sample IDs must be unique.\n",
+    "* Null values such as `numpy.nan` are allowed and represent missing values."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "<class 'pandas.core.frame.DataFrame'>\n",
+      "Index: 3 entries, sample_0 to sample_2\n",
+      "Data columns (total 2 columns):\n",
+      " #   Column    Non-Null Count  Dtype  \n",
+      "---  ------    --------------  -----  \n",
+      " 0   s_feat_0  3 non-null      int64  \n",
+      " 1   s_feat_1  2 non-null      float64\n",
+      "dtypes: float64(1), int64(1)\n",
+      "memory usage: 72.0+ bytes\n"
+     ]
+    },
+    {
+     "data": {
+      "text/html": [
+       "<div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th>s_feat_0</th>\n",
+       "      <th>s_feat_1</th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th>sample_0</th>\n",
+       "      <td>100</td>\n",
+       "      <td>-1.1</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_1</th>\n",
+       "      <td>200</td>\n",
+       "      <td>NaN</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_2</th>\n",
+       "      <td>300</td>\n",
+       "      <td>-1.3</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "          s_feat_0  s_feat_1\n",
+       "sample_0       100      -1.1\n",
+       "sample_1       200       NaN\n",
+       "sample_2       300      -1.3"
+      ]
+     },
+     "execution_count": 4,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# Create a static data dataframe.\n",
+    "\n",
+    "static_df = pd.DataFrame(\n",
+    "    {\n",
+    "        \"s_feat_0\": [100, 200, 300],\n",
+    "        \"s_feat_1\": [-1.1, np.nan, -1.3],\n",
+    "    },\n",
+    "    index=[\"sample_0\", \"sample_1\", \"sample_2\"],\n",
+    ")\n",
+    "\n",
+    "# Preview the dataframe:\n",
+    "static_df.info()\n",
+    "static_df"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Event data\n",
+    "\n",
+    "Event data contains data samples (e.g. patients), with features that represent occurrence of an event at a certain time.\n",
+    "If the event did not occur, it is \"censored\".\n",
+    "\n",
+    "Event data should take form of a `pandas.DataFrame`, with the following specifics:\n",
+    "* The index represents sample IDs and is a (single level) index that can be comprised of `int`s or `str`s (homogenous, not a mix of these).\n",
+    "* The columns of the dataframe represent the features, column names must be `str`.\n",
+    "* Column (feature) values must be of the form: `Tuple[<timestep>, bool]`.\n",
+    "    * The first element `<timestep>` may be `int`, `float` or `pandas.Timestep`-compatible format (homogenous per column).\n",
+    "    * The second element `bool` indicates whether the event occurred at this time (`True`) or the event feature is censored (`False`).\n",
+    "    * In case of censoring, the timestep should indicate the last time information about the sample was available. \n",
+    "\n",
+    "Other points to note:\n",
+    "* Sample IDs must be unique.\n",
+    "* Null values such as `numpy.nan` are not allowed allowed - indicate an event as censored (did not occur) instead."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "<class 'pandas.core.frame.DataFrame'>\n",
+      "Index: 3 entries, sample_0 to sample_2\n",
+      "Data columns (total 2 columns):\n",
+      " #   Column    Non-Null Count  Dtype \n",
+      "---  ------    --------------  ----- \n",
+      " 0   e_feat_0  3 non-null      object\n",
+      " 1   e_feat_1  3 non-null      object\n",
+      "dtypes: object(2)\n",
+      "memory usage: 72.0+ bytes\n"
+     ]
+    },
+    {
+     "data": {
+      "text/html": [
+       "<div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th>e_feat_0</th>\n",
+       "      <th>e_feat_1</th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th>sample_0</th>\n",
+       "      <td>(10, True)</td>\n",
+       "      <td>(10, False)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_1</th>\n",
+       "      <td>(12, False)</td>\n",
+       "      <td>(10, False)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_2</th>\n",
+       "      <td>(13, True)</td>\n",
+       "      <td>(11, True)</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "             e_feat_0     e_feat_1\n",
+       "sample_0   (10, True)  (10, False)\n",
+       "sample_1  (12, False)  (10, False)\n",
+       "sample_2   (13, True)   (11, True)"
+      ]
+     },
+     "execution_count": 5,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# Create an event dataframe.\n",
+    "\n",
+    "event_df = pd.DataFrame(\n",
+    "    {\n",
+    "        \"e_feat_0\": [(10, True), (12, False), (13, True)],\n",
+    "        \"e_feat_1\": [(10, False), (10, False), (11, True)],\n",
+    "    },\n",
+    "    index=[\"sample_0\", \"sample_1\", \"sample_2\"],\n",
+    ")\n",
+    "\n",
+    "# Preview the dataframe:\n",
+    "event_df.info()\n",
+    "event_df"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "The data can also be initialised from a 2D `numpy` array (static, event) or a 3D `numpy` array (time series).\n",
+    "\n",
+    "`TODO: more info`"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Dataset\n",
+    "\n",
+    "The collection of data that represents the task at hand is a `Dataset`.\n",
+    "\n",
+    "A `Dataset` contains:\n",
+    "* Time series data (covariates),\n",
+    "* Static data (covariates), optional,\n",
+    "* Predictive data, which depends on the *task*.\n",
+    "    * This may contain *targets* and *treatments*.\n",
+    "\n",
+    "For example, for the *time-to-event analysis task* we create a dataset as follows."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "TimeToEventAnalysisDataset(\n",
+       "    time_series=TimeSeriesSamples([3, *, 3]),\n",
+       "    static=StaticSamples([3, 2]),\n",
+       "    predictive=TimeToEventAnalysisTaskData(targets=EventSamples([3, 2]))\n",
+       ")"
+      ]
+     },
+     "execution_count": 6,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "from tempor.data.dataset import TimeToEventAnalysisDataset\n",
+    "\n",
+    "# Create a dataset of time-to-event analysis task:\n",
+    "data = TimeToEventAnalysisDataset(\n",
+    "    time_series=time_series_df,\n",
+    "    static=static_df,\n",
+    "    targets=event_df,\n",
+    ")\n",
+    "\n",
+    "# Preview dataset:\n",
+    "data"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<p><span style=\"font-family: monospace;\">TimeSeriesSamples</span> with data:</p><div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th>t_feat_0</th>\n",
+       "      <th>t_feat_1</th>\n",
+       "      <th>t_feat_2</th>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_idx</th>\n",
+       "      <th>time_idx</th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"4\" valign=\"top\">sample_0</th>\n",
+       "      <th>1</th>\n",
+       "      <td>11</td>\n",
+       "      <td>1.1</td>\n",
+       "      <td>a</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>2</th>\n",
+       "      <td>12</td>\n",
+       "      <td>1.2</td>\n",
+       "      <td>b</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>3</th>\n",
+       "      <td>13</td>\n",
+       "      <td>1.3</td>\n",
+       "      <td>b</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>14</td>\n",
+       "      <td>NaN</td>\n",
+       "      <td>c</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"2\" valign=\"top\">sample_1</th>\n",
+       "      <th>2</th>\n",
+       "      <td>21</td>\n",
+       "      <td>2.1</td>\n",
+       "      <td>a</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>22</td>\n",
+       "      <td>2.2</td>\n",
+       "      <td>a</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_2</th>\n",
+       "      <th>9</th>\n",
+       "      <td>31</td>\n",
+       "      <td>3.1</td>\n",
+       "      <td>c</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "TimeSeriesSamples with data:\n",
+       "                     t_feat_0  t_feat_1 t_feat_2\n",
+       "sample_idx time_idx                             \n",
+       "sample_0   1               11       1.1        a\n",
+       "           2               12       1.2        b\n",
+       "           3               13       1.3        b\n",
+       "           4               14       NaN        c\n",
+       "sample_1   2               21       2.1        a\n",
+       "           4               22       2.2        a\n",
+       "sample_2   9               31       3.1        c"
+      ]
+     },
+     "execution_count": 7,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "data.time_series"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<p><span style=\"font-family: monospace;\">StaticSamples</span> with data:</p><div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th>s_feat_0</th>\n",
+       "      <th>s_feat_1</th>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_idx</th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th>sample_0</th>\n",
+       "      <td>100</td>\n",
+       "      <td>-1.1</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_1</th>\n",
+       "      <td>200</td>\n",
+       "      <td>NaN</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_2</th>\n",
+       "      <td>300</td>\n",
+       "      <td>-1.3</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "StaticSamples with data:\n",
+       "            s_feat_0  s_feat_1\n",
+       "sample_idx                    \n",
+       "sample_0         100      -1.1\n",
+       "sample_1         200       NaN\n",
+       "sample_2         300      -1.3"
+      ]
+     },
+     "execution_count": 8,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "data.static"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<p><span style=\"font-family: monospace;\">EventSamples</span> with data:</p><div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th>e_feat_0</th>\n",
+       "      <th>e_feat_1</th>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_idx</th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th>sample_0</th>\n",
+       "      <td>(10, True)</td>\n",
+       "      <td>(10, False)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_1</th>\n",
+       "      <td>(12, False)</td>\n",
+       "      <td>(10, False)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_2</th>\n",
+       "      <td>(13, True)</td>\n",
+       "      <td>(11, True)</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "EventSamples with data:\n",
+       "               e_feat_0     e_feat_1\n",
+       "sample_idx                          \n",
+       "sample_0     (10, True)  (10, False)\n",
+       "sample_1    (12, False)  (10, False)\n",
+       "sample_2     (13, True)   (11, True)"
+      ]
+     },
+     "execution_count": 9,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "data.predictive.targets"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Useful methods\n",
+    "\n",
+    "The data (`{TimeSeries,Event,Static}Samples` classes) provide a number of useful methods, some examples below."
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Examples for `TimeSeriesSamples`"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 25,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "time_series = data.time_series"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 26,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th>t_feat_0</th>\n",
+       "      <th>t_feat_1</th>\n",
+       "      <th>t_feat_2</th>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_idx</th>\n",
+       "      <th>time_idx</th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"4\" valign=\"top\">sample_0</th>\n",
+       "      <th>1</th>\n",
+       "      <td>11</td>\n",
+       "      <td>1.1</td>\n",
+       "      <td>a</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>2</th>\n",
+       "      <td>12</td>\n",
+       "      <td>1.2</td>\n",
+       "      <td>b</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>3</th>\n",
+       "      <td>13</td>\n",
+       "      <td>1.3</td>\n",
+       "      <td>b</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>14</td>\n",
+       "      <td>NaN</td>\n",
+       "      <td>c</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"2\" valign=\"top\">sample_1</th>\n",
+       "      <th>2</th>\n",
+       "      <td>21</td>\n",
+       "      <td>2.1</td>\n",
+       "      <td>a</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>22</td>\n",
+       "      <td>2.2</td>\n",
+       "      <td>a</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_2</th>\n",
+       "      <th>9</th>\n",
+       "      <td>31</td>\n",
+       "      <td>3.1</td>\n",
+       "      <td>c</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "                     t_feat_0  t_feat_1 t_feat_2\n",
+       "sample_idx time_idx                             \n",
+       "sample_0   1               11       1.1        a\n",
+       "           2               12       1.2        b\n",
+       "           3               13       1.3        b\n",
+       "           4               14       NaN        c\n",
+       "sample_1   2               21       2.1        a\n",
+       "           4               22       2.2        a\n",
+       "sample_2   9               31       3.1        c"
+      ]
+     },
+     "execution_count": 26,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# Return time series data as a dataframe:\n",
+    "\n",
+    "time_series.dataframe()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 27,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "array([[[11, 1.1, 'a'],\n",
+       "        [12, 1.2, 'b'],\n",
+       "        [13, 1.3, 'b'],\n",
+       "        [14, nan, 'c']],\n",
+       "\n",
+       "       [[21, 2.1, 'a'],\n",
+       "        [22, 2.2, 'a'],\n",
+       "        [-999.0, -999.0, -999.0],\n",
+       "        [-999.0, -999.0, -999.0]],\n",
+       "\n",
+       "       [[31, 3.1, 'c'],\n",
+       "        [-999.0, -999.0, -999.0],\n",
+       "        [-999.0, -999.0, -999.0],\n",
+       "        [-999.0, -999.0, -999.0]]], dtype=object)"
+      ]
+     },
+     "execution_count": 27,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# Return time series data as a numpy array:\n",
+    "\n",
+    "time_series.numpy(padding_indicator=-999.0)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 28,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[                     t_feat_0  t_feat_1 t_feat_2\n",
+       " sample_idx time_idx                             \n",
+       " sample_0   1               11       1.1        a\n",
+       "            2               12       1.2        b\n",
+       "            3               13       1.3        b\n",
+       "            4               14       NaN        c,\n",
+       "                      t_feat_0  t_feat_1 t_feat_2\n",
+       " sample_idx time_idx                             \n",
+       " sample_1   2               21       2.1        a\n",
+       "            4               22       2.2        a,\n",
+       "                      t_feat_0  t_feat_1 t_feat_2\n",
+       " sample_idx time_idx                             \n",
+       " sample_2   9               31       3.1        c]"
+      ]
+     },
+     "execution_count": 28,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# Return the time series data as a list of dataframes:\n",
+    "\n",
+    "time_series.list_of_dataframes()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 29,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "num_features: 3\n",
+      "num_samples: 3\n"
+     ]
+    }
+   ],
+   "source": [
+    "# Show number of features and samples:\n",
+    "\n",
+    "print(\"num_features:\", time_series.num_features)\n",
+    "print(\"num_samples:\", time_series.num_samples)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 30,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "timesteps per sample: [4, 2, 1]\n"
+     ]
+    }
+   ],
+   "source": [
+    "# Show number of samples for each sample:\n",
+    "\n",
+    "print(\"timesteps per sample:\", time_series.num_timesteps())"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Examples for `{Static,Event}Samples`"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 33,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "assert data.static is not None\n",
+    "assert data.predictive.targets is not None\n",
+    "\n",
+    "static = data.static\n",
+    "event = data.predictive.targets"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 34,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th>s_feat_0</th>\n",
+       "      <th>s_feat_1</th>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_idx</th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th>sample_0</th>\n",
+       "      <td>100</td>\n",
+       "      <td>-1.1</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_1</th>\n",
+       "      <td>200</td>\n",
+       "      <td>NaN</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_2</th>\n",
+       "      <td>300</td>\n",
+       "      <td>-1.3</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "            s_feat_0  s_feat_1\n",
+       "sample_idx                    \n",
+       "sample_0         100      -1.1\n",
+       "sample_1         200       NaN\n",
+       "sample_2         300      -1.3"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "array([[100. ,  -1.1],\n",
+       "       [200. ,   nan],\n",
+       "       [300. ,  -1.3]])"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "# Return the static data as a dataframe, numpy array:\n",
+    "\n",
+    "display(static.dataframe())\n",
+    "display(static.numpy())"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 35,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th>e_feat_0</th>\n",
+       "      <th>e_feat_1</th>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_idx</th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th>sample_0</th>\n",
+       "      <td>(10, True)</td>\n",
+       "      <td>(10, False)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_1</th>\n",
+       "      <td>(12, False)</td>\n",
+       "      <td>(10, False)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_2</th>\n",
+       "      <td>(13, True)</td>\n",
+       "      <td>(11, True)</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "               e_feat_0     e_feat_1\n",
+       "sample_idx                          \n",
+       "sample_0     (10, True)  (10, False)\n",
+       "sample_1    (12, False)  (10, False)\n",
+       "sample_2     (13, True)   (11, True)"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "array([[(10, True), (10, False)],\n",
+       "       [(12, False), (10, False)],\n",
+       "       [(13, True), (11, True)]], dtype=object)"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "# Return the event data as a dataframe, numpy array:\n",
+    "\n",
+    "display(event.dataframe())\n",
+    "display(event.numpy())"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## 🎉 Congratulations!\n",
+    "\n",
+    "Congratulations on completing this notebook tutorial! If you enjoyed this and would like to join the movement towards *Machine learning and AI for Medicine*, you can do so in the following ways!\n",
+    "\n",
+    "\n",
+    "\n",
+    "### ⭐ Star [TemporAI](https://github.com/vanderschaarlab/temporai) on GitHub\n",
+    "\n",
+    "- The easiest way to help our community is by just starring the repos! This helps raise awareness of the tools we're building.\n",
+    "\n",
+    "\n",
+    "\n",
+    "### Check out other projects from [vanderschaarlab](https://github.com/vanderschaarlab)\n",
+    "- 📝 [HyperImpute](https://github.com/vanderschaarlab/hyperimpute)\n",
+    "- 📊 [AutoPrognosis](https://github.com/vanderschaarlab/autoprognosis)\n",
+    "- 🤖 [SynthCity](https://github.com/vanderschaarlab/synthcity)\n",
+    " "
+   ]
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "RE_py38_temporai",
+   "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.15"
+  },
+  "orig_nbformat": 4
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/tutorials/data/tutorial02_datasets.ipynb b/tutorials/data/tutorial02_datasets.ipynb
new file mode 100644
index 00000000..fe9ec36c
--- /dev/null
+++ b/tutorials/data/tutorial02_datasets.ipynb
@@ -0,0 +1,2344 @@
+{
+ "cells": [
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Data Tutorial 02: Datasets\n",
+    "\n",
+    "This tutorial shows different TemporAI `Dataset`s."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "*Skip the below cell if you are not on Google Colab / already have TemporAI installed:*"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "%pip install temporai\n",
+    "\n",
+    "# Or from the repo, for the latest version:\n",
+    "# %pip install git+https://github.com/vanderschaarlab/temporai.git"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## 0. Prepare some example data"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import pandas as pd\n",
+    "import numpy as np\n",
+    "\n",
+    "# Some time series data:\n",
+    "time_series_df = pd.DataFrame(\n",
+    "    {\n",
+    "        \"sample_idx\": [\"sample_0\", \"sample_0\", \"sample_0\", \"sample_0\", \"sample_1\", \"sample_1\", \"sample_2\"],\n",
+    "        \"time_idx\": [1, 2, 3, 4, 2, 4, 9],\n",
+    "        \"t_feat_0\": [11, 12, 13, 14, 21, 22, 31],\n",
+    "        \"t_feat_1\": [1.1, 1.2, 1.3, 1.4, 2.1, 2.2, 3.1],\n",
+    "        \"t_feat_2\": [10, 20, 30, 40, 11, 21, 111],\n",
+    "    }\n",
+    ")\n",
+    "time_series_df.set_index(keys=[\"sample_idx\", \"time_idx\"], drop=True, inplace=True)\n",
+    "\n",
+    "# Some static data:\n",
+    "static_df = pd.DataFrame(\n",
+    "    {\n",
+    "        \"s_feat_0\": [100, 200, 300],\n",
+    "        \"s_feat_1\": [-1.1, -1.2, -1.3],\n",
+    "        \"s_feat_2\": [0, 1, 0],\n",
+    "    },\n",
+    "    index=[\"sample_0\", \"sample_1\", \"sample_2\"],\n",
+    ")\n",
+    "\n",
+    "event_df = pd.DataFrame(\n",
+    "    {\n",
+    "        \"e_feat_0\": [(10, True), (12, False), (13, True)],\n",
+    "        \"e_feat_1\": [(10, False), (10, False), (11, True)],\n",
+    "    },\n",
+    "    index=[\"sample_0\", \"sample_1\", \"sample_2\"],\n",
+    ")"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Preview the dataframes below."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th>t_feat_0</th>\n",
+       "      <th>t_feat_1</th>\n",
+       "      <th>t_feat_2</th>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_idx</th>\n",
+       "      <th>time_idx</th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"4\" valign=\"top\">sample_0</th>\n",
+       "      <th>1</th>\n",
+       "      <td>11</td>\n",
+       "      <td>1.1</td>\n",
+       "      <td>10</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>2</th>\n",
+       "      <td>12</td>\n",
+       "      <td>1.2</td>\n",
+       "      <td>20</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>3</th>\n",
+       "      <td>13</td>\n",
+       "      <td>1.3</td>\n",
+       "      <td>30</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>14</td>\n",
+       "      <td>1.4</td>\n",
+       "      <td>40</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"2\" valign=\"top\">sample_1</th>\n",
+       "      <th>2</th>\n",
+       "      <td>21</td>\n",
+       "      <td>2.1</td>\n",
+       "      <td>11</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>22</td>\n",
+       "      <td>2.2</td>\n",
+       "      <td>21</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_2</th>\n",
+       "      <th>9</th>\n",
+       "      <td>31</td>\n",
+       "      <td>3.1</td>\n",
+       "      <td>111</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "                     t_feat_0  t_feat_1  t_feat_2\n",
+       "sample_idx time_idx                              \n",
+       "sample_0   1               11       1.1        10\n",
+       "           2               12       1.2        20\n",
+       "           3               13       1.3        30\n",
+       "           4               14       1.4        40\n",
+       "sample_1   2               21       2.1        11\n",
+       "           4               22       2.2        21\n",
+       "sample_2   9               31       3.1       111"
+      ]
+     },
+     "execution_count": 3,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "time_series_df"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th>s_feat_0</th>\n",
+       "      <th>s_feat_1</th>\n",
+       "      <th>s_feat_2</th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th>sample_0</th>\n",
+       "      <td>100</td>\n",
+       "      <td>-1.1</td>\n",
+       "      <td>0</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_1</th>\n",
+       "      <td>200</td>\n",
+       "      <td>-1.2</td>\n",
+       "      <td>1</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_2</th>\n",
+       "      <td>300</td>\n",
+       "      <td>-1.3</td>\n",
+       "      <td>0</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "          s_feat_0  s_feat_1  s_feat_2\n",
+       "sample_0       100      -1.1         0\n",
+       "sample_1       200      -1.2         1\n",
+       "sample_2       300      -1.3         0"
+      ]
+     },
+     "execution_count": 4,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "static_df"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th>e_feat_0</th>\n",
+       "      <th>e_feat_1</th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th>sample_0</th>\n",
+       "      <td>(10, True)</td>\n",
+       "      <td>(10, False)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_1</th>\n",
+       "      <td>(12, False)</td>\n",
+       "      <td>(10, False)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_2</th>\n",
+       "      <td>(13, True)</td>\n",
+       "      <td>(11, True)</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "             e_feat_0     e_feat_1\n",
+       "sample_0   (10, True)  (10, False)\n",
+       "sample_1  (12, False)  (10, False)\n",
+       "sample_2   (13, True)   (11, True)"
+      ]
+     },
+     "execution_count": 5,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "event_df"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## 1. `CovariatesDataset`\n",
+    "\n",
+    "A `CovariatesDataset` contains time series and optionally static covariates only, without any predictive data\n",
+    "(targets or treatments).\n",
+    "\n",
+    "It can be used with `preprocessing` transformations."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from tempor.data import dataset"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "CovariatesDataset(\n",
+       "    time_series=TimeSeriesSamples([3, *, 3]),\n",
+       "    static=StaticSamples([3, 3])\n",
+       ")"
+      ]
+     },
+     "execution_count": 7,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# Initialize a CovariatesDataset:\n",
+    "data = dataset.CovariatesDataset(\n",
+    "    time_series=time_series_df,\n",
+    "    static=static_df,  # Optional, can be `None`.\n",
+    ")\n",
+    "\n",
+    "data"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<p><span style=\"font-family: monospace;\">TimeSeriesSamples</span> with data:</p><div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th>t_feat_0</th>\n",
+       "      <th>t_feat_1</th>\n",
+       "      <th>t_feat_2</th>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_idx</th>\n",
+       "      <th>time_idx</th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"4\" valign=\"top\">sample_0</th>\n",
+       "      <th>1</th>\n",
+       "      <td>11</td>\n",
+       "      <td>1.1</td>\n",
+       "      <td>10</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>2</th>\n",
+       "      <td>12</td>\n",
+       "      <td>1.2</td>\n",
+       "      <td>20</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>3</th>\n",
+       "      <td>13</td>\n",
+       "      <td>1.3</td>\n",
+       "      <td>30</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>14</td>\n",
+       "      <td>1.4</td>\n",
+       "      <td>40</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"2\" valign=\"top\">sample_1</th>\n",
+       "      <th>2</th>\n",
+       "      <td>21</td>\n",
+       "      <td>2.1</td>\n",
+       "      <td>11</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>22</td>\n",
+       "      <td>2.2</td>\n",
+       "      <td>21</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_2</th>\n",
+       "      <th>9</th>\n",
+       "      <td>31</td>\n",
+       "      <td>3.1</td>\n",
+       "      <td>111</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "TimeSeriesSamples with data:\n",
+       "                     t_feat_0  t_feat_1  t_feat_2\n",
+       "sample_idx time_idx                              \n",
+       "sample_0   1               11       1.1        10\n",
+       "           2               12       1.2        20\n",
+       "           3               13       1.3        30\n",
+       "           4               14       1.4        40\n",
+       "sample_1   2               21       2.1        11\n",
+       "           4               22       2.2        21\n",
+       "sample_2   9               31       3.1       111"
+      ]
+     },
+     "execution_count": 8,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "data.time_series"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<p><span style=\"font-family: monospace;\">StaticSamples</span> with data:</p><div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th>s_feat_0</th>\n",
+       "      <th>s_feat_1</th>\n",
+       "      <th>s_feat_2</th>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_idx</th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th>sample_0</th>\n",
+       "      <td>100</td>\n",
+       "      <td>-1.1</td>\n",
+       "      <td>0</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_1</th>\n",
+       "      <td>200</td>\n",
+       "      <td>-1.2</td>\n",
+       "      <td>1</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_2</th>\n",
+       "      <td>300</td>\n",
+       "      <td>-1.3</td>\n",
+       "      <td>0</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "StaticSamples with data:\n",
+       "            s_feat_0  s_feat_1  s_feat_2\n",
+       "sample_idx                              \n",
+       "sample_0         100      -1.1         0\n",
+       "sample_1         200      -1.2         1\n",
+       "sample_2         300      -1.3         0"
+      ]
+     },
+     "execution_count": 9,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "data.static"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## 1. `OneOffPredictionDataset`\n",
+    "\n",
+    "A `OneOffPredictionDataset` contains time series and optionally static covariates.\n",
+    "\n",
+    "It also needs `StaticSamples` prediction *targets* for estimators to be able to `fit` on this dataset.\n",
+    "\n",
+    "It can be used with `prediction.one_off` estimators. The task is to predict some one-off value for each sample."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "OneOffPredictionDataset(\n",
+       "    time_series=TimeSeriesSamples([3, *, 3]),\n",
+       "    static=StaticSamples([3, 2]),\n",
+       "    predictive=OneOffPredictionTaskData(targets=StaticSamples([3, 1]))\n",
+       ")"
+      ]
+     },
+     "execution_count": 10,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# Initialize a OneOffPredictionDataset:\n",
+    "data = dataset.OneOffPredictionDataset(\n",
+    "    time_series=time_series_df,\n",
+    "    static=static_df.loc[:, :\"s_feat_1\"],  # Optional, can be `None`.\n",
+    "    targets=static_df.loc[:, [\"s_feat_2\"]],  # Optional, can be `None` at inference time.\n",
+    ")\n",
+    "\n",
+    "data"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<p><span style=\"font-family: monospace;\">TimeSeriesSamples</span> with data:</p><div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th>t_feat_0</th>\n",
+       "      <th>t_feat_1</th>\n",
+       "      <th>t_feat_2</th>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_idx</th>\n",
+       "      <th>time_idx</th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"4\" valign=\"top\">sample_0</th>\n",
+       "      <th>1</th>\n",
+       "      <td>11</td>\n",
+       "      <td>1.1</td>\n",
+       "      <td>10</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>2</th>\n",
+       "      <td>12</td>\n",
+       "      <td>1.2</td>\n",
+       "      <td>20</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>3</th>\n",
+       "      <td>13</td>\n",
+       "      <td>1.3</td>\n",
+       "      <td>30</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>14</td>\n",
+       "      <td>1.4</td>\n",
+       "      <td>40</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"2\" valign=\"top\">sample_1</th>\n",
+       "      <th>2</th>\n",
+       "      <td>21</td>\n",
+       "      <td>2.1</td>\n",
+       "      <td>11</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>22</td>\n",
+       "      <td>2.2</td>\n",
+       "      <td>21</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_2</th>\n",
+       "      <th>9</th>\n",
+       "      <td>31</td>\n",
+       "      <td>3.1</td>\n",
+       "      <td>111</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "TimeSeriesSamples with data:\n",
+       "                     t_feat_0  t_feat_1  t_feat_2\n",
+       "sample_idx time_idx                              \n",
+       "sample_0   1               11       1.1        10\n",
+       "           2               12       1.2        20\n",
+       "           3               13       1.3        30\n",
+       "           4               14       1.4        40\n",
+       "sample_1   2               21       2.1        11\n",
+       "           4               22       2.2        21\n",
+       "sample_2   9               31       3.1       111"
+      ]
+     },
+     "execution_count": 11,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "data.time_series"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<p><span style=\"font-family: monospace;\">StaticSamples</span> with data:</p><div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th>s_feat_0</th>\n",
+       "      <th>s_feat_1</th>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_idx</th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th>sample_0</th>\n",
+       "      <td>100</td>\n",
+       "      <td>-1.1</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_1</th>\n",
+       "      <td>200</td>\n",
+       "      <td>-1.2</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_2</th>\n",
+       "      <td>300</td>\n",
+       "      <td>-1.3</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "StaticSamples with data:\n",
+       "            s_feat_0  s_feat_1\n",
+       "sample_idx                    \n",
+       "sample_0         100      -1.1\n",
+       "sample_1         200      -1.2\n",
+       "sample_2         300      -1.3"
+      ]
+     },
+     "execution_count": 12,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "data.static"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<p><span style=\"font-family: monospace;\">StaticSamples</span> with data:</p><div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th>s_feat_2</th>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_idx</th>\n",
+       "      <th></th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th>sample_0</th>\n",
+       "      <td>0</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_1</th>\n",
+       "      <td>1</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_2</th>\n",
+       "      <td>0</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "StaticSamples with data:\n",
+       "            s_feat_2\n",
+       "sample_idx          \n",
+       "sample_0           0\n",
+       "sample_1           1\n",
+       "sample_2           0"
+      ]
+     },
+     "execution_count": 13,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "data.predictive.targets"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## 1. `TemporalPredictionDataset`\n",
+    "\n",
+    "A `TemporalPredictionDataset` contains time series and optionally static covariates.\n",
+    "\n",
+    "It also needs `TimeSeriesSamples` prediction *targets* for estimators to be able to `fit` on this dataset.\n",
+    "\n",
+    "It can be used with `prediction.temporal` estimators. The task is to predict some time series for each sample."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "TemporalPredictionDataset(\n",
+       "    time_series=TimeSeriesSamples([3, *, 2]),\n",
+       "    static=StaticSamples([3, 3]),\n",
+       "    predictive=TemporalPredictionTaskData(\n",
+       "        targets=TimeSeriesSamples([3, *, 1])\n",
+       "    )\n",
+       ")"
+      ]
+     },
+     "execution_count": 14,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# Initialize a TemporalPredictionDataset:\n",
+    "data = dataset.TemporalPredictionDataset(\n",
+    "    time_series=time_series_df.loc[:, :\"t_feat_1\"],\n",
+    "    static=static_df,  # Optional, can be `None`.\n",
+    "    targets=time_series_df.loc[:, [\"t_feat_2\"]],  # Optional, can be `None` at inference time.\n",
+    ")\n",
+    "\n",
+    "data"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<p><span style=\"font-family: monospace;\">TimeSeriesSamples</span> with data:</p><div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th>t_feat_0</th>\n",
+       "      <th>t_feat_1</th>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_idx</th>\n",
+       "      <th>time_idx</th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"4\" valign=\"top\">sample_0</th>\n",
+       "      <th>1</th>\n",
+       "      <td>11</td>\n",
+       "      <td>1.1</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>2</th>\n",
+       "      <td>12</td>\n",
+       "      <td>1.2</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>3</th>\n",
+       "      <td>13</td>\n",
+       "      <td>1.3</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>14</td>\n",
+       "      <td>1.4</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"2\" valign=\"top\">sample_1</th>\n",
+       "      <th>2</th>\n",
+       "      <td>21</td>\n",
+       "      <td>2.1</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>22</td>\n",
+       "      <td>2.2</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_2</th>\n",
+       "      <th>9</th>\n",
+       "      <td>31</td>\n",
+       "      <td>3.1</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "TimeSeriesSamples with data:\n",
+       "                     t_feat_0  t_feat_1\n",
+       "sample_idx time_idx                    \n",
+       "sample_0   1               11       1.1\n",
+       "           2               12       1.2\n",
+       "           3               13       1.3\n",
+       "           4               14       1.4\n",
+       "sample_1   2               21       2.1\n",
+       "           4               22       2.2\n",
+       "sample_2   9               31       3.1"
+      ]
+     },
+     "execution_count": 15,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "data.time_series"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<p><span style=\"font-family: monospace;\">StaticSamples</span> with data:</p><div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th>s_feat_0</th>\n",
+       "      <th>s_feat_1</th>\n",
+       "      <th>s_feat_2</th>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_idx</th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th>sample_0</th>\n",
+       "      <td>100</td>\n",
+       "      <td>-1.1</td>\n",
+       "      <td>0</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_1</th>\n",
+       "      <td>200</td>\n",
+       "      <td>-1.2</td>\n",
+       "      <td>1</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_2</th>\n",
+       "      <td>300</td>\n",
+       "      <td>-1.3</td>\n",
+       "      <td>0</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "StaticSamples with data:\n",
+       "            s_feat_0  s_feat_1  s_feat_2\n",
+       "sample_idx                              \n",
+       "sample_0         100      -1.1         0\n",
+       "sample_1         200      -1.2         1\n",
+       "sample_2         300      -1.3         0"
+      ]
+     },
+     "execution_count": 16,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "data.static"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 17,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<p><span style=\"font-family: monospace;\">TimeSeriesSamples</span> with data:</p><div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th>t_feat_2</th>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_idx</th>\n",
+       "      <th>time_idx</th>\n",
+       "      <th></th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"4\" valign=\"top\">sample_0</th>\n",
+       "      <th>1</th>\n",
+       "      <td>10</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>2</th>\n",
+       "      <td>20</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>3</th>\n",
+       "      <td>30</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>40</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"2\" valign=\"top\">sample_1</th>\n",
+       "      <th>2</th>\n",
+       "      <td>11</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>21</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_2</th>\n",
+       "      <th>9</th>\n",
+       "      <td>111</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "TimeSeriesSamples with data:\n",
+       "                     t_feat_2\n",
+       "sample_idx time_idx          \n",
+       "sample_0   1               10\n",
+       "           2               20\n",
+       "           3               30\n",
+       "           4               40\n",
+       "sample_1   2               11\n",
+       "           4               21\n",
+       "sample_2   9              111"
+      ]
+     },
+     "execution_count": 17,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "data.predictive.targets"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## 1. `TimeToEventAnalysisDataset`\n",
+    "\n",
+    "A `TimeToEventAnalysisDataset` contains time series and optionally static covariates.\n",
+    "\n",
+    "It also needs `EventSamples` prediction *targets* for estimators to be able to `fit` on this dataset.\n",
+    "\n",
+    "It can be used with `time_to_event` estimators. The task is to predict risk scores for each sample."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 18,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "TimeToEventAnalysisDataset(\n",
+       "    time_series=TimeSeriesSamples([3, *, 3]),\n",
+       "    static=StaticSamples([3, 3]),\n",
+       "    predictive=TimeToEventAnalysisTaskData(targets=EventSamples([3, 2]))\n",
+       ")"
+      ]
+     },
+     "execution_count": 18,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# Initialize a TimeToEventAnalysisDataset:\n",
+    "data = dataset.TimeToEventAnalysisDataset(\n",
+    "    time_series=time_series_df,\n",
+    "    static=static_df,  # Optional, can be `None`.\n",
+    "    targets=event_df,  # Optional, can be `None` at inference time.\n",
+    ")\n",
+    "\n",
+    "data"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 19,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<p><span style=\"font-family: monospace;\">TimeSeriesSamples</span> with data:</p><div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th>t_feat_0</th>\n",
+       "      <th>t_feat_1</th>\n",
+       "      <th>t_feat_2</th>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_idx</th>\n",
+       "      <th>time_idx</th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"4\" valign=\"top\">sample_0</th>\n",
+       "      <th>1</th>\n",
+       "      <td>11</td>\n",
+       "      <td>1.1</td>\n",
+       "      <td>10</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>2</th>\n",
+       "      <td>12</td>\n",
+       "      <td>1.2</td>\n",
+       "      <td>20</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>3</th>\n",
+       "      <td>13</td>\n",
+       "      <td>1.3</td>\n",
+       "      <td>30</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>14</td>\n",
+       "      <td>1.4</td>\n",
+       "      <td>40</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"2\" valign=\"top\">sample_1</th>\n",
+       "      <th>2</th>\n",
+       "      <td>21</td>\n",
+       "      <td>2.1</td>\n",
+       "      <td>11</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>22</td>\n",
+       "      <td>2.2</td>\n",
+       "      <td>21</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_2</th>\n",
+       "      <th>9</th>\n",
+       "      <td>31</td>\n",
+       "      <td>3.1</td>\n",
+       "      <td>111</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "TimeSeriesSamples with data:\n",
+       "                     t_feat_0  t_feat_1  t_feat_2\n",
+       "sample_idx time_idx                              \n",
+       "sample_0   1               11       1.1        10\n",
+       "           2               12       1.2        20\n",
+       "           3               13       1.3        30\n",
+       "           4               14       1.4        40\n",
+       "sample_1   2               21       2.1        11\n",
+       "           4               22       2.2        21\n",
+       "sample_2   9               31       3.1       111"
+      ]
+     },
+     "execution_count": 19,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "data.time_series"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 20,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<p><span style=\"font-family: monospace;\">StaticSamples</span> with data:</p><div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th>s_feat_0</th>\n",
+       "      <th>s_feat_1</th>\n",
+       "      <th>s_feat_2</th>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_idx</th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th>sample_0</th>\n",
+       "      <td>100</td>\n",
+       "      <td>-1.1</td>\n",
+       "      <td>0</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_1</th>\n",
+       "      <td>200</td>\n",
+       "      <td>-1.2</td>\n",
+       "      <td>1</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_2</th>\n",
+       "      <td>300</td>\n",
+       "      <td>-1.3</td>\n",
+       "      <td>0</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "StaticSamples with data:\n",
+       "            s_feat_0  s_feat_1  s_feat_2\n",
+       "sample_idx                              \n",
+       "sample_0         100      -1.1         0\n",
+       "sample_1         200      -1.2         1\n",
+       "sample_2         300      -1.3         0"
+      ]
+     },
+     "execution_count": 20,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "data.static"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 21,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<p><span style=\"font-family: monospace;\">EventSamples</span> with data:</p><div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th>e_feat_0</th>\n",
+       "      <th>e_feat_1</th>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_idx</th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th>sample_0</th>\n",
+       "      <td>(10, True)</td>\n",
+       "      <td>(10, False)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_1</th>\n",
+       "      <td>(12, False)</td>\n",
+       "      <td>(10, False)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_2</th>\n",
+       "      <td>(13, True)</td>\n",
+       "      <td>(11, True)</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "EventSamples with data:\n",
+       "               e_feat_0     e_feat_1\n",
+       "sample_idx                          \n",
+       "sample_0     (10, True)  (10, False)\n",
+       "sample_1    (12, False)  (10, False)\n",
+       "sample_2     (13, True)   (11, True)"
+      ]
+     },
+     "execution_count": 21,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "data.predictive.targets"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## 1. `OneOffTreatmentEffectsDataset`\n",
+    "\n",
+    "A `OneOffTreatmentEffectsDataset` contains time series and optionally static covariates.\n",
+    "\n",
+    "It also needs `TimeSeriesSamples` prediction *targets* and `EventSamples` treatments\n",
+    "for estimators to be able to `fit` on this dataset.\n",
+    "\n",
+    "It can be used with `treatments.one_off` estimators.\n",
+    "The task is to predict a time series counterfactual outcome based on a one-off treatment event."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 22,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "OneOffTreatmentEffectsDataset(\n",
+       "    time_series=TimeSeriesSamples([3, *, 2]),\n",
+       "    static=StaticSamples([3, 3]),\n",
+       "    predictive=OneOffTreatmentEffectsTaskData(\n",
+       "        targets=TimeSeriesSamples([3, *, 1]),\n",
+       "        treatments=EventSamples([3, 1])\n",
+       "    )\n",
+       ")"
+      ]
+     },
+     "execution_count": 22,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# Initialize a TimeToEventAnalysisDataset:\n",
+    "data = dataset.OneOffTreatmentEffectsDataset(\n",
+    "    time_series=time_series_df.loc[:, :\"t_feat_1\"],\n",
+    "    static=static_df,  # Optional, can be `None`.\n",
+    "    targets=time_series_df.loc[:, [\"t_feat_2\"]],  # Optional, can be `None` at inference time.\n",
+    "    treatments=event_df.loc[:, [\"e_feat_0\"]],\n",
+    ")\n",
+    "\n",
+    "data"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 23,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<p><span style=\"font-family: monospace;\">TimeSeriesSamples</span> with data:</p><div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th>t_feat_0</th>\n",
+       "      <th>t_feat_1</th>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_idx</th>\n",
+       "      <th>time_idx</th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"4\" valign=\"top\">sample_0</th>\n",
+       "      <th>1</th>\n",
+       "      <td>11</td>\n",
+       "      <td>1.1</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>2</th>\n",
+       "      <td>12</td>\n",
+       "      <td>1.2</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>3</th>\n",
+       "      <td>13</td>\n",
+       "      <td>1.3</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>14</td>\n",
+       "      <td>1.4</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"2\" valign=\"top\">sample_1</th>\n",
+       "      <th>2</th>\n",
+       "      <td>21</td>\n",
+       "      <td>2.1</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>22</td>\n",
+       "      <td>2.2</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_2</th>\n",
+       "      <th>9</th>\n",
+       "      <td>31</td>\n",
+       "      <td>3.1</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "TimeSeriesSamples with data:\n",
+       "                     t_feat_0  t_feat_1\n",
+       "sample_idx time_idx                    \n",
+       "sample_0   1               11       1.1\n",
+       "           2               12       1.2\n",
+       "           3               13       1.3\n",
+       "           4               14       1.4\n",
+       "sample_1   2               21       2.1\n",
+       "           4               22       2.2\n",
+       "sample_2   9               31       3.1"
+      ]
+     },
+     "execution_count": 23,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "data.time_series"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 24,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<p><span style=\"font-family: monospace;\">StaticSamples</span> with data:</p><div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th>s_feat_0</th>\n",
+       "      <th>s_feat_1</th>\n",
+       "      <th>s_feat_2</th>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_idx</th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th>sample_0</th>\n",
+       "      <td>100</td>\n",
+       "      <td>-1.1</td>\n",
+       "      <td>0</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_1</th>\n",
+       "      <td>200</td>\n",
+       "      <td>-1.2</td>\n",
+       "      <td>1</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_2</th>\n",
+       "      <td>300</td>\n",
+       "      <td>-1.3</td>\n",
+       "      <td>0</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "StaticSamples with data:\n",
+       "            s_feat_0  s_feat_1  s_feat_2\n",
+       "sample_idx                              \n",
+       "sample_0         100      -1.1         0\n",
+       "sample_1         200      -1.2         1\n",
+       "sample_2         300      -1.3         0"
+      ]
+     },
+     "execution_count": 24,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "data.static"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 25,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<p><span style=\"font-family: monospace;\">TimeSeriesSamples</span> with data:</p><div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th>t_feat_2</th>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_idx</th>\n",
+       "      <th>time_idx</th>\n",
+       "      <th></th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"4\" valign=\"top\">sample_0</th>\n",
+       "      <th>1</th>\n",
+       "      <td>10</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>2</th>\n",
+       "      <td>20</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>3</th>\n",
+       "      <td>30</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>40</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"2\" valign=\"top\">sample_1</th>\n",
+       "      <th>2</th>\n",
+       "      <td>11</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>21</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_2</th>\n",
+       "      <th>9</th>\n",
+       "      <td>111</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "TimeSeriesSamples with data:\n",
+       "                     t_feat_2\n",
+       "sample_idx time_idx          \n",
+       "sample_0   1               10\n",
+       "           2               20\n",
+       "           3               30\n",
+       "           4               40\n",
+       "sample_1   2               11\n",
+       "           4               21\n",
+       "sample_2   9              111"
+      ]
+     },
+     "execution_count": 25,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "data.predictive.targets"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 26,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<p><span style=\"font-family: monospace;\">EventSamples</span> with data:</p><div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th>e_feat_0</th>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_idx</th>\n",
+       "      <th></th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th>sample_0</th>\n",
+       "      <td>(10, True)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_1</th>\n",
+       "      <td>(12, False)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_2</th>\n",
+       "      <td>(13, True)</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "EventSamples with data:\n",
+       "               e_feat_0\n",
+       "sample_idx             \n",
+       "sample_0     (10, True)\n",
+       "sample_1    (12, False)\n",
+       "sample_2     (13, True)"
+      ]
+     },
+     "execution_count": 26,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "data.predictive.treatments"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## 1. `TemporalTreatmentEffectsDataset`\n",
+    "\n",
+    "A `TemporalTreatmentEffectsDataset` contains time series and optionally static covariates.\n",
+    "\n",
+    "It also needs `TimeSeriesSamples` prediction *targets* and `TimeSeriesSamples` treatments\n",
+    "for estimators to be able to `fit` on this dataset.\n",
+    "\n",
+    "It can be used with `treatments.temporal` estimators.\n",
+    "The task is to predict a time series counterfactual outcome based on a time series treatment."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 27,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "TemporalTreatmentEffectsDataset(\n",
+       "    time_series=TimeSeriesSamples([3, *, 1]),\n",
+       "    static=StaticSamples([3, 3]),\n",
+       "    predictive=TemporalTreatmentEffectsTaskData(\n",
+       "        targets=TimeSeriesSamples([3, *, 1]),\n",
+       "        treatments=TimeSeriesSamples([3, *, 1])\n",
+       "    )\n",
+       ")"
+      ]
+     },
+     "execution_count": 27,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# Initialize a TimeToEventAnalysisDataset:\n",
+    "data = dataset.TemporalTreatmentEffectsDataset(\n",
+    "    time_series=time_series_df.loc[:, :\"t_feat_0\"],\n",
+    "    static=static_df,  # Optional, can be `None`.\n",
+    "    targets=time_series_df.loc[:, [\"t_feat_1\"]],  # Optional, can be `None` at inference time.\n",
+    "    treatments=time_series_df.loc[:, [\"t_feat_2\"]],\n",
+    ")\n",
+    "\n",
+    "data"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 28,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<p><span style=\"font-family: monospace;\">TimeSeriesSamples</span> with data:</p><div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th>t_feat_0</th>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_idx</th>\n",
+       "      <th>time_idx</th>\n",
+       "      <th></th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"4\" valign=\"top\">sample_0</th>\n",
+       "      <th>1</th>\n",
+       "      <td>11</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>2</th>\n",
+       "      <td>12</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>3</th>\n",
+       "      <td>13</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>14</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"2\" valign=\"top\">sample_1</th>\n",
+       "      <th>2</th>\n",
+       "      <td>21</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>22</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_2</th>\n",
+       "      <th>9</th>\n",
+       "      <td>31</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "TimeSeriesSamples with data:\n",
+       "                     t_feat_0\n",
+       "sample_idx time_idx          \n",
+       "sample_0   1               11\n",
+       "           2               12\n",
+       "           3               13\n",
+       "           4               14\n",
+       "sample_1   2               21\n",
+       "           4               22\n",
+       "sample_2   9               31"
+      ]
+     },
+     "execution_count": 28,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "data.time_series"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 29,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<p><span style=\"font-family: monospace;\">StaticSamples</span> with data:</p><div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th>s_feat_0</th>\n",
+       "      <th>s_feat_1</th>\n",
+       "      <th>s_feat_2</th>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_idx</th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th>sample_0</th>\n",
+       "      <td>100</td>\n",
+       "      <td>-1.1</td>\n",
+       "      <td>0</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_1</th>\n",
+       "      <td>200</td>\n",
+       "      <td>-1.2</td>\n",
+       "      <td>1</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_2</th>\n",
+       "      <td>300</td>\n",
+       "      <td>-1.3</td>\n",
+       "      <td>0</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "StaticSamples with data:\n",
+       "            s_feat_0  s_feat_1  s_feat_2\n",
+       "sample_idx                              \n",
+       "sample_0         100      -1.1         0\n",
+       "sample_1         200      -1.2         1\n",
+       "sample_2         300      -1.3         0"
+      ]
+     },
+     "execution_count": 29,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "data.static"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 30,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<p><span style=\"font-family: monospace;\">TimeSeriesSamples</span> with data:</p><div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th>t_feat_1</th>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_idx</th>\n",
+       "      <th>time_idx</th>\n",
+       "      <th></th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"4\" valign=\"top\">sample_0</th>\n",
+       "      <th>1</th>\n",
+       "      <td>1.1</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>2</th>\n",
+       "      <td>1.2</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>3</th>\n",
+       "      <td>1.3</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>1.4</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"2\" valign=\"top\">sample_1</th>\n",
+       "      <th>2</th>\n",
+       "      <td>2.1</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>2.2</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_2</th>\n",
+       "      <th>9</th>\n",
+       "      <td>3.1</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "TimeSeriesSamples with data:\n",
+       "                     t_feat_1\n",
+       "sample_idx time_idx          \n",
+       "sample_0   1              1.1\n",
+       "           2              1.2\n",
+       "           3              1.3\n",
+       "           4              1.4\n",
+       "sample_1   2              2.1\n",
+       "           4              2.2\n",
+       "sample_2   9              3.1"
+      ]
+     },
+     "execution_count": 30,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "data.predictive.targets"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 31,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<p><span style=\"font-family: monospace;\">TimeSeriesSamples</span> with data:</p><div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th>t_feat_2</th>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_idx</th>\n",
+       "      <th>time_idx</th>\n",
+       "      <th></th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"4\" valign=\"top\">sample_0</th>\n",
+       "      <th>1</th>\n",
+       "      <td>10</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>2</th>\n",
+       "      <td>20</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>3</th>\n",
+       "      <td>30</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>40</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"2\" valign=\"top\">sample_1</th>\n",
+       "      <th>2</th>\n",
+       "      <td>11</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>21</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_2</th>\n",
+       "      <th>9</th>\n",
+       "      <td>111</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "TimeSeriesSamples with data:\n",
+       "                     t_feat_2\n",
+       "sample_idx time_idx          \n",
+       "sample_0   1               10\n",
+       "           2               20\n",
+       "           3               30\n",
+       "           4               40\n",
+       "sample_1   2               11\n",
+       "           4               21\n",
+       "sample_2   9              111"
+      ]
+     },
+     "execution_count": 31,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "data.predictive.treatments"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## 🎉 Congratulations!\n",
+    "\n",
+    "Congratulations on completing this notebook tutorial! If you enjoyed this and would like to join the movement towards *Machine learning and AI for Medicine*, you can do so in the following ways!\n",
+    "\n",
+    "\n",
+    "\n",
+    "### ⭐ Star [TemporAI](https://github.com/vanderschaarlab/temporai) on GitHub\n",
+    "\n",
+    "- The easiest way to help our community is by just starring the repos! This helps raise awareness of the tools we're building.\n",
+    "\n",
+    "\n",
+    "\n",
+    "### Check out other projects from [vanderschaarlab](https://github.com/vanderschaarlab)\n",
+    "- 📝 [HyperImpute](https://github.com/vanderschaarlab/hyperimpute)\n",
+    "- 📊 [AutoPrognosis](https://github.com/vanderschaarlab/autoprognosis)\n",
+    "- 🤖 [SynthCity](https://github.com/vanderschaarlab/synthcity)\n",
+    " "
+   ]
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "RE_py38_temporai",
+   "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.15"
+  },
+  "orig_nbformat": 4
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/tutorials/data/tutorial03_dataloaders.ipynb b/tutorials/data/tutorial03_dataloaders.ipynb
new file mode 100644
index 00000000..383e91b6
--- /dev/null
+++ b/tutorials/data/tutorial03_dataloaders.ipynb
@@ -0,0 +1,3601 @@
+{
+ "cells": [
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Data Tutorial 03: Data loaders\n",
+    "\n",
+    "This tutorial shows TemporAI `Dataloader`s."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "*Skip the below cell if you are not on Google Colab / already have TemporAI installed:*"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "%pip install temporai\n",
+    "\n",
+    "# Or from the repo, for the latest version:\n",
+    "# %pip install git+https://github.com/vanderschaarlab/temporai.git"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## `Dataloader` class\n",
+    "\n",
+    "A TemporAI `Dataloader` implements a `load()` method which returns a TemporAI dataset.\n",
+    "\n",
+    "`Dataloader`s are useful to load in some custom datasets, having done the necessary preprocessing,\n",
+    "perhaps user-configured.\n",
+    "\n",
+    "Below is an example of `SineDataLoader`."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "tempor.utils.dataloaders.sine.SineDataLoader"
+      ]
+     },
+     "execution_count": 2,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "from tempor.utils.dataloaders import SineDataLoader\n",
+    "\n",
+    "# The DataLoader class:\n",
+    "SineDataLoader"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "The constructor of the `Dataloader` can take various keyword arguments - this is where the user may customize the data\n",
+    "preprocessing etc."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "<tempor.utils.dataloaders.sine.SineDataLoader at 0x7f8155017fa0>"
+      ]
+     },
+     "execution_count": 3,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# Initialize.\n",
+    "\n",
+    "sine_dataloader = SineDataLoader(\n",
+    "    no=80,  # Here, number of samples.\n",
+    "    seq_len=5,  # Here, time series sequence length.\n",
+    "    # ...\n",
+    ")\n",
+    "\n",
+    "sine_dataloader"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "<class 'tempor.data.dataset.OneOffPredictionDataset'>\n"
+     ]
+    },
+    {
+     "data": {
+      "text/plain": [
+       "OneOffPredictionDataset(\n",
+       "    time_series=TimeSeriesSamples([80, *, 5]),\n",
+       "    static=StaticSamples([80, 4]),\n",
+       "    predictive=OneOffPredictionTaskData(targets=StaticSamples([80, 1]))\n",
+       ")"
+      ]
+     },
+     "execution_count": 4,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# Load the Dataset:\n",
+    "data = sine_dataloader.load()\n",
+    "\n",
+    "print(type(data))\n",
+    "\n",
+    "data"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<p><span style=\"font-family: monospace;\">TimeSeriesSamples</span> with data:</p><div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th>0</th>\n",
+       "      <th>1</th>\n",
+       "      <th>2</th>\n",
+       "      <th>3</th>\n",
+       "      <th>4</th>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_idx</th>\n",
+       "      <th>time_idx</th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"5\" valign=\"top\">0</th>\n",
+       "      <th>0</th>\n",
+       "      <td>-0.151203</td>\n",
+       "      <td>0.206110</td>\n",
+       "      <td>0.783078</td>\n",
+       "      <td>0.768667</td>\n",
+       "      <td>0.957344</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>1</th>\n",
+       "      <td>0.679518</td>\n",
+       "      <td>0.785370</td>\n",
+       "      <td>0.913243</td>\n",
+       "      <td>0.999923</td>\n",
+       "      <td>0.973799</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>2</th>\n",
+       "      <td>0.997174</td>\n",
+       "      <td>0.999603</td>\n",
+       "      <td>0.985913</td>\n",
+       "      <td>0.784278</td>\n",
+       "      <td>0.730349</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>3</th>\n",
+       "      <td>0.561921</td>\n",
+       "      <td>0.749235</td>\n",
+       "      <td>0.996514</td>\n",
+       "      <td>0.218111</td>\n",
+       "      <td>0.291970</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>-0.297606</td>\n",
+       "      <td>0.150635</td>\n",
+       "      <td>0.944377</td>\n",
+       "      <td>-0.445537</td>\n",
+       "      <td>-0.224335</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>...</th>\n",
+       "      <th>...</th>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"5\" valign=\"top\">79</th>\n",
+       "      <th>0</th>\n",
+       "      <td>0.999730</td>\n",
+       "      <td>0.101680</td>\n",
+       "      <td>-0.976039</td>\n",
+       "      <td>-0.999547</td>\n",
+       "      <td>-0.715265</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>1</th>\n",
+       "      <td>0.803590</td>\n",
+       "      <td>0.577241</td>\n",
+       "      <td>-0.696389</td>\n",
+       "      <td>-0.897416</td>\n",
+       "      <td>-0.312411</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>2</th>\n",
+       "      <td>0.269220</td>\n",
+       "      <td>0.903914</td>\n",
+       "      <td>-0.188132</td>\n",
+       "      <td>-0.586595</td>\n",
+       "      <td>0.160840</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>3</th>\n",
+       "      <td>-0.378464</td>\n",
+       "      <td>0.997443</td>\n",
+       "      <td>0.381883</td>\n",
+       "      <td>-0.139366</td>\n",
+       "      <td>0.597849</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>-0.866853</td>\n",
+       "      <td>0.833703</td>\n",
+       "      <td>0.826536</td>\n",
+       "      <td>0.340273</td>\n",
+       "      <td>0.900138</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "<p>400 rows × 5 columns</p>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "TimeSeriesSamples with data:\n",
+       "                            0         1         2         3         4\n",
+       "sample_idx time_idx                                                  \n",
+       "0          0        -0.151203  0.206110  0.783078  0.768667  0.957344\n",
+       "           1         0.679518  0.785370  0.913243  0.999923  0.973799\n",
+       "           2         0.997174  0.999603  0.985913  0.784278  0.730349\n",
+       "           3         0.561921  0.749235  0.996514  0.218111  0.291970\n",
+       "           4        -0.297606  0.150635  0.944377 -0.445537 -0.224335\n",
+       "...                       ...       ...       ...       ...       ...\n",
+       "79         0         0.999730  0.101680 -0.976039 -0.999547 -0.715265\n",
+       "           1         0.803590  0.577241 -0.696389 -0.897416 -0.312411\n",
+       "           2         0.269220  0.903914 -0.188132 -0.586595  0.160840\n",
+       "           3        -0.378464  0.997443  0.381883 -0.139366  0.597849\n",
+       "           4        -0.866853  0.833703  0.826536  0.340273  0.900138\n",
+       "\n",
+       "[400 rows x 5 columns]"
+      ]
+     },
+     "execution_count": 5,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "data.time_series"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<p><span style=\"font-family: monospace;\">StaticSamples</span> with data:</p><div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th>0</th>\n",
+       "      <th>1</th>\n",
+       "      <th>2</th>\n",
+       "      <th>3</th>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_idx</th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th>0</th>\n",
+       "      <td>0.374540</td>\n",
+       "      <td>0.950714</td>\n",
+       "      <td>0.731994</td>\n",
+       "      <td>0.598658</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>1</th>\n",
+       "      <td>0.156019</td>\n",
+       "      <td>0.155995</td>\n",
+       "      <td>0.058084</td>\n",
+       "      <td>0.866176</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>2</th>\n",
+       "      <td>0.601115</td>\n",
+       "      <td>0.708073</td>\n",
+       "      <td>0.020584</td>\n",
+       "      <td>0.969910</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>3</th>\n",
+       "      <td>0.832443</td>\n",
+       "      <td>0.212339</td>\n",
+       "      <td>0.181825</td>\n",
+       "      <td>0.183405</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>0.304242</td>\n",
+       "      <td>0.524756</td>\n",
+       "      <td>0.431945</td>\n",
+       "      <td>0.291229</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>...</th>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>75</th>\n",
+       "      <td>0.051682</td>\n",
+       "      <td>0.531355</td>\n",
+       "      <td>0.540635</td>\n",
+       "      <td>0.637430</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>76</th>\n",
+       "      <td>0.726091</td>\n",
+       "      <td>0.975852</td>\n",
+       "      <td>0.516300</td>\n",
+       "      <td>0.322956</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>77</th>\n",
+       "      <td>0.795186</td>\n",
+       "      <td>0.270832</td>\n",
+       "      <td>0.438971</td>\n",
+       "      <td>0.078456</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>78</th>\n",
+       "      <td>0.025351</td>\n",
+       "      <td>0.962648</td>\n",
+       "      <td>0.835980</td>\n",
+       "      <td>0.695974</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>79</th>\n",
+       "      <td>0.408953</td>\n",
+       "      <td>0.173294</td>\n",
+       "      <td>0.156437</td>\n",
+       "      <td>0.250243</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "<p>80 rows × 4 columns</p>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "StaticSamples with data:\n",
+       "                   0         1         2         3\n",
+       "sample_idx                                        \n",
+       "0           0.374540  0.950714  0.731994  0.598658\n",
+       "1           0.156019  0.155995  0.058084  0.866176\n",
+       "2           0.601115  0.708073  0.020584  0.969910\n",
+       "3           0.832443  0.212339  0.181825  0.183405\n",
+       "4           0.304242  0.524756  0.431945  0.291229\n",
+       "...              ...       ...       ...       ...\n",
+       "75          0.051682  0.531355  0.540635  0.637430\n",
+       "76          0.726091  0.975852  0.516300  0.322956\n",
+       "77          0.795186  0.270832  0.438971  0.078456\n",
+       "78          0.025351  0.962648  0.835980  0.695974\n",
+       "79          0.408953  0.173294  0.156437  0.250243\n",
+       "\n",
+       "[80 rows x 4 columns]"
+      ]
+     },
+     "execution_count": 6,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "data.static"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<p><span style=\"font-family: monospace;\">StaticSamples</span> with data:</p><div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th>0</th>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_idx</th>\n",
+       "      <th></th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th>0</th>\n",
+       "      <td>1</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>1</th>\n",
+       "      <td>1</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>2</th>\n",
+       "      <td>1</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>3</th>\n",
+       "      <td>0</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>1</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>...</th>\n",
+       "      <td>...</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>75</th>\n",
+       "      <td>1</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>76</th>\n",
+       "      <td>0</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>77</th>\n",
+       "      <td>1</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>78</th>\n",
+       "      <td>1</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>79</th>\n",
+       "      <td>1</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "<p>80 rows × 1 columns</p>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "StaticSamples with data:\n",
+       "            0\n",
+       "sample_idx   \n",
+       "0           1\n",
+       "1           1\n",
+       "2           1\n",
+       "3           0\n",
+       "4           1\n",
+       "...        ..\n",
+       "75          1\n",
+       "76          0\n",
+       "77          1\n",
+       "78          1\n",
+       "79          1\n",
+       "\n",
+       "[80 rows x 1 columns]"
+      ]
+     },
+     "execution_count": 7,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "data.predictive.targets"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Provided `Dataloader`s\n",
+    "\n",
+    "TemporAI comes with a number of dataloaders, see below."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 21,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "\n",
+      "--------------------------------------------------------------------------------\n",
+      "\n",
+      "DummyTemporalPredictionDataLoader loads the following dataset:\n",
+      "\n",
+      "TemporalPredictionDataset(\n",
+      "    time_series=TimeSeriesSamples([100, *, 5]),\n",
+      "    static=StaticSamples([100, 3]),\n",
+      "    predictive=TemporalPredictionTaskData(\n",
+      "        targets=TimeSeriesSamples([100, *, 2])\n",
+      "    )\n",
+      ")\n",
+      "This contains:\n",
+      "\n",
+      "time_series:\n"
+     ]
+    },
+    {
+     "data": {
+      "text/html": [
+       "<p><span style=\"font-family: monospace;\">TimeSeriesSamples</span> with data:</p><div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th>0</th>\n",
+       "      <th>1</th>\n",
+       "      <th>2</th>\n",
+       "      <th>3</th>\n",
+       "      <th>4</th>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_idx</th>\n",
+       "      <th>time_idx</th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"5\" valign=\"top\">0</th>\n",
+       "      <th>0</th>\n",
+       "      <td>NaN</td>\n",
+       "      <td>0.893763</td>\n",
+       "      <td>NaN</td>\n",
+       "      <td>NaN</td>\n",
+       "      <td>1.047522</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>1</th>\n",
+       "      <td>1.257931</td>\n",
+       "      <td>2.172271</td>\n",
+       "      <td>2.226089</td>\n",
+       "      <td>2.360713</td>\n",
+       "      <td>1.981578</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>2</th>\n",
+       "      <td>2.247657</td>\n",
+       "      <td>0.853397</td>\n",
+       "      <td>2.525946</td>\n",
+       "      <td>3.213647</td>\n",
+       "      <td>2.897191</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>3</th>\n",
+       "      <td>3.396456</td>\n",
+       "      <td>5.386071</td>\n",
+       "      <td>3.721545</td>\n",
+       "      <td>2.503248</td>\n",
+       "      <td>3.517212</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>4.387812</td>\n",
+       "      <td>3.365264</td>\n",
+       "      <td>5.612532</td>\n",
+       "      <td>5.573375</td>\n",
+       "      <td>4.767746</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>...</th>\n",
+       "      <th>...</th>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"5\" valign=\"top\">99</th>\n",
+       "      <th>12</th>\n",
+       "      <td>12.654769</td>\n",
+       "      <td>14.810888</td>\n",
+       "      <td>12.914859</td>\n",
+       "      <td>NaN</td>\n",
+       "      <td>12.818675</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>13</th>\n",
+       "      <td>13.418815</td>\n",
+       "      <td>12.135655</td>\n",
+       "      <td>12.481295</td>\n",
+       "      <td>13.336797</td>\n",
+       "      <td>13.696168</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>14</th>\n",
+       "      <td>13.785503</td>\n",
+       "      <td>14.431228</td>\n",
+       "      <td>15.193174</td>\n",
+       "      <td>17.551818</td>\n",
+       "      <td>14.464249</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>15</th>\n",
+       "      <td>15.344934</td>\n",
+       "      <td>15.916966</td>\n",
+       "      <td>14.368132</td>\n",
+       "      <td>15.965113</td>\n",
+       "      <td>15.419334</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>16</th>\n",
+       "      <td>16.033907</td>\n",
+       "      <td>15.162631</td>\n",
+       "      <td>17.338485</td>\n",
+       "      <td>17.007235</td>\n",
+       "      <td>17.034645</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "<p>1547 rows × 5 columns</p>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "TimeSeriesSamples with data:\n",
+       "                             0          1          2          3          4\n",
+       "sample_idx time_idx                                                       \n",
+       "0          0               NaN   0.893763        NaN        NaN   1.047522\n",
+       "           1          1.257931   2.172271   2.226089   2.360713   1.981578\n",
+       "           2          2.247657   0.853397   2.525946   3.213647   2.897191\n",
+       "           3          3.396456   5.386071   3.721545   2.503248   3.517212\n",
+       "           4          4.387812   3.365264   5.612532   5.573375   4.767746\n",
+       "...                        ...        ...        ...        ...        ...\n",
+       "99         12        12.654769  14.810888  12.914859        NaN  12.818675\n",
+       "           13        13.418815  12.135655  12.481295  13.336797  13.696168\n",
+       "           14        13.785503  14.431228  15.193174  17.551818  14.464249\n",
+       "           15        15.344934  15.916966  14.368132  15.965113  15.419334\n",
+       "           16        16.033907  15.162631  17.338485  17.007235  17.034645\n",
+       "\n",
+       "[1547 rows x 5 columns]"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "static:\n"
+     ]
+    },
+    {
+     "data": {
+      "text/html": [
+       "<p><span style=\"font-family: monospace;\">StaticSamples</span> with data:</p><div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th>0</th>\n",
+       "      <th>1</th>\n",
+       "      <th>2</th>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_idx</th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th>0</th>\n",
+       "      <td>0.753423</td>\n",
+       "      <td>3.239284</td>\n",
+       "      <td>0.995587</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>1</th>\n",
+       "      <td>0.829240</td>\n",
+       "      <td>3.175298</td>\n",
+       "      <td>0.770566</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>2</th>\n",
+       "      <td>0.674581</td>\n",
+       "      <td>3.229741</td>\n",
+       "      <td>1.302317</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>3</th>\n",
+       "      <td>0.584040</td>\n",
+       "      <td>3.234011</td>\n",
+       "      <td>1.594861</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>0.501552</td>\n",
+       "      <td>3.211027</td>\n",
+       "      <td>0.639503</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>...</th>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>95</th>\n",
+       "      <td>0.680235</td>\n",
+       "      <td>3.287749</td>\n",
+       "      <td>0.705369</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>96</th>\n",
+       "      <td>0.788814</td>\n",
+       "      <td>3.313229</td>\n",
+       "      <td>1.318394</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>97</th>\n",
+       "      <td>0.589116</td>\n",
+       "      <td>3.268607</td>\n",
+       "      <td>1.646737</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>98</th>\n",
+       "      <td>0.551060</td>\n",
+       "      <td>3.268599</td>\n",
+       "      <td>0.998024</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>99</th>\n",
+       "      <td>0.716501</td>\n",
+       "      <td>3.254501</td>\n",
+       "      <td>1.047537</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "<p>100 rows × 3 columns</p>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "StaticSamples with data:\n",
+       "                   0         1         2\n",
+       "sample_idx                              \n",
+       "0           0.753423  3.239284  0.995587\n",
+       "1           0.829240  3.175298  0.770566\n",
+       "2           0.674581  3.229741  1.302317\n",
+       "3           0.584040  3.234011  1.594861\n",
+       "4           0.501552  3.211027  0.639503\n",
+       "...              ...       ...       ...\n",
+       "95          0.680235  3.287749  0.705369\n",
+       "96          0.788814  3.313229  1.318394\n",
+       "97          0.589116  3.268607  1.646737\n",
+       "98          0.551060  3.268599  0.998024\n",
+       "99          0.716501  3.254501  1.047537\n",
+       "\n",
+       "[100 rows x 3 columns]"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "predictive.targets:\n"
+     ]
+    },
+    {
+     "data": {
+      "text/html": [
+       "<p><span style=\"font-family: monospace;\">TimeSeriesSamples</span> with data:</p><div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th>0</th>\n",
+       "      <th>1</th>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_idx</th>\n",
+       "      <th>time_idx</th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"5\" valign=\"top\">0</th>\n",
+       "      <th>0</th>\n",
+       "      <td>-1.433570</td>\n",
+       "      <td>0.714861</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>1</th>\n",
+       "      <td>-0.600733</td>\n",
+       "      <td>2.744446</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>2</th>\n",
+       "      <td>0.622874</td>\n",
+       "      <td>1.816995</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>3</th>\n",
+       "      <td>1.879785</td>\n",
+       "      <td>4.981217</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>2.477957</td>\n",
+       "      <td>5.932101</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>...</th>\n",
+       "      <th>...</th>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"5\" valign=\"top\">99</th>\n",
+       "      <th>12</th>\n",
+       "      <td>10.736462</td>\n",
+       "      <td>13.415872</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>13</th>\n",
+       "      <td>11.617465</td>\n",
+       "      <td>15.103293</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>14</th>\n",
+       "      <td>12.858327</td>\n",
+       "      <td>16.105966</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>15</th>\n",
+       "      <td>13.652358</td>\n",
+       "      <td>16.148926</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>16</th>\n",
+       "      <td>14.442286</td>\n",
+       "      <td>17.567963</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "<p>1547 rows × 2 columns</p>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "TimeSeriesSamples with data:\n",
+       "                             0          1\n",
+       "sample_idx time_idx                      \n",
+       "0          0         -1.433570   0.714861\n",
+       "           1         -0.600733   2.744446\n",
+       "           2          0.622874   1.816995\n",
+       "           3          1.879785   4.981217\n",
+       "           4          2.477957   5.932101\n",
+       "...                        ...        ...\n",
+       "99         12        10.736462  13.415872\n",
+       "           13        11.617465  15.103293\n",
+       "           14        12.858327  16.105966\n",
+       "           15        13.652358  16.148926\n",
+       "           16        14.442286  17.567963\n",
+       "\n",
+       "[1547 rows x 2 columns]"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "\n",
+      "--------------------------------------------------------------------------------\n",
+      "\n",
+      "DummyTemporalTreatmentEffectsDataLoader loads the following dataset:\n",
+      "\n",
+      "TemporalTreatmentEffectsDataset(\n",
+      "    time_series=TimeSeriesSamples([100, *, 5]),\n",
+      "    static=StaticSamples([100, 3]),\n",
+      "    predictive=TemporalTreatmentEffectsTaskData(\n",
+      "        targets=TimeSeriesSamples([100, *, 2]),\n",
+      "        treatments=TimeSeriesSamples([100, *, 2])\n",
+      "    )\n",
+      ")\n",
+      "This contains:\n",
+      "\n",
+      "time_series:\n"
+     ]
+    },
+    {
+     "data": {
+      "text/html": [
+       "<p><span style=\"font-family: monospace;\">TimeSeriesSamples</span> with data:</p><div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th>0</th>\n",
+       "      <th>1</th>\n",
+       "      <th>2</th>\n",
+       "      <th>3</th>\n",
+       "      <th>4</th>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_idx</th>\n",
+       "      <th>time_idx</th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"5\" valign=\"top\">0</th>\n",
+       "      <th>0</th>\n",
+       "      <td>NaN</td>\n",
+       "      <td>0.893763</td>\n",
+       "      <td>NaN</td>\n",
+       "      <td>NaN</td>\n",
+       "      <td>1.047522</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>1</th>\n",
+       "      <td>1.257931</td>\n",
+       "      <td>2.172271</td>\n",
+       "      <td>2.226089</td>\n",
+       "      <td>2.360713</td>\n",
+       "      <td>1.981578</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>2</th>\n",
+       "      <td>2.247657</td>\n",
+       "      <td>0.853397</td>\n",
+       "      <td>2.525946</td>\n",
+       "      <td>3.213647</td>\n",
+       "      <td>2.897191</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>3</th>\n",
+       "      <td>3.396456</td>\n",
+       "      <td>5.386071</td>\n",
+       "      <td>3.721545</td>\n",
+       "      <td>2.503248</td>\n",
+       "      <td>3.517212</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>4.387812</td>\n",
+       "      <td>3.365264</td>\n",
+       "      <td>5.612532</td>\n",
+       "      <td>5.573375</td>\n",
+       "      <td>4.767746</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>...</th>\n",
+       "      <th>...</th>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"5\" valign=\"top\">99</th>\n",
+       "      <th>12</th>\n",
+       "      <td>12.654769</td>\n",
+       "      <td>14.810888</td>\n",
+       "      <td>12.914859</td>\n",
+       "      <td>NaN</td>\n",
+       "      <td>12.818675</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>13</th>\n",
+       "      <td>13.418815</td>\n",
+       "      <td>12.135655</td>\n",
+       "      <td>12.481295</td>\n",
+       "      <td>13.336797</td>\n",
+       "      <td>13.696168</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>14</th>\n",
+       "      <td>13.785503</td>\n",
+       "      <td>14.431228</td>\n",
+       "      <td>15.193174</td>\n",
+       "      <td>17.551818</td>\n",
+       "      <td>14.464249</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>15</th>\n",
+       "      <td>15.344934</td>\n",
+       "      <td>15.916966</td>\n",
+       "      <td>14.368132</td>\n",
+       "      <td>15.965113</td>\n",
+       "      <td>15.419334</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>16</th>\n",
+       "      <td>16.033907</td>\n",
+       "      <td>15.162631</td>\n",
+       "      <td>17.338485</td>\n",
+       "      <td>17.007235</td>\n",
+       "      <td>17.034645</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "<p>1547 rows × 5 columns</p>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "TimeSeriesSamples with data:\n",
+       "                             0          1          2          3          4\n",
+       "sample_idx time_idx                                                       \n",
+       "0          0               NaN   0.893763        NaN        NaN   1.047522\n",
+       "           1          1.257931   2.172271   2.226089   2.360713   1.981578\n",
+       "           2          2.247657   0.853397   2.525946   3.213647   2.897191\n",
+       "           3          3.396456   5.386071   3.721545   2.503248   3.517212\n",
+       "           4          4.387812   3.365264   5.612532   5.573375   4.767746\n",
+       "...                        ...        ...        ...        ...        ...\n",
+       "99         12        12.654769  14.810888  12.914859        NaN  12.818675\n",
+       "           13        13.418815  12.135655  12.481295  13.336797  13.696168\n",
+       "           14        13.785503  14.431228  15.193174  17.551818  14.464249\n",
+       "           15        15.344934  15.916966  14.368132  15.965113  15.419334\n",
+       "           16        16.033907  15.162631  17.338485  17.007235  17.034645\n",
+       "\n",
+       "[1547 rows x 5 columns]"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "static:\n"
+     ]
+    },
+    {
+     "data": {
+      "text/html": [
+       "<p><span style=\"font-family: monospace;\">StaticSamples</span> with data:</p><div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th>0</th>\n",
+       "      <th>1</th>\n",
+       "      <th>2</th>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_idx</th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th>0</th>\n",
+       "      <td>0.753423</td>\n",
+       "      <td>3.239284</td>\n",
+       "      <td>0.995587</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>1</th>\n",
+       "      <td>0.829240</td>\n",
+       "      <td>3.175298</td>\n",
+       "      <td>0.770566</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>2</th>\n",
+       "      <td>0.674581</td>\n",
+       "      <td>3.229741</td>\n",
+       "      <td>1.302317</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>3</th>\n",
+       "      <td>0.584040</td>\n",
+       "      <td>3.234011</td>\n",
+       "      <td>1.594861</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>0.501552</td>\n",
+       "      <td>3.211027</td>\n",
+       "      <td>0.639503</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>...</th>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>95</th>\n",
+       "      <td>0.680235</td>\n",
+       "      <td>3.287749</td>\n",
+       "      <td>0.705369</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>96</th>\n",
+       "      <td>0.788814</td>\n",
+       "      <td>3.313229</td>\n",
+       "      <td>1.318394</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>97</th>\n",
+       "      <td>0.589116</td>\n",
+       "      <td>3.268607</td>\n",
+       "      <td>1.646737</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>98</th>\n",
+       "      <td>0.551060</td>\n",
+       "      <td>3.268599</td>\n",
+       "      <td>0.998024</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>99</th>\n",
+       "      <td>0.716501</td>\n",
+       "      <td>3.254501</td>\n",
+       "      <td>1.047537</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "<p>100 rows × 3 columns</p>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "StaticSamples with data:\n",
+       "                   0         1         2\n",
+       "sample_idx                              \n",
+       "0           0.753423  3.239284  0.995587\n",
+       "1           0.829240  3.175298  0.770566\n",
+       "2           0.674581  3.229741  1.302317\n",
+       "3           0.584040  3.234011  1.594861\n",
+       "4           0.501552  3.211027  0.639503\n",
+       "...              ...       ...       ...\n",
+       "95          0.680235  3.287749  0.705369\n",
+       "96          0.788814  3.313229  1.318394\n",
+       "97          0.589116  3.268607  1.646737\n",
+       "98          0.551060  3.268599  0.998024\n",
+       "99          0.716501  3.254501  1.047537\n",
+       "\n",
+       "[100 rows x 3 columns]"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "predictive.targets:\n"
+     ]
+    },
+    {
+     "data": {
+      "text/html": [
+       "<p><span style=\"font-family: monospace;\">TimeSeriesSamples</span> with data:</p><div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th>0</th>\n",
+       "      <th>1</th>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_idx</th>\n",
+       "      <th>time_idx</th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"5\" valign=\"top\">0</th>\n",
+       "      <th>0</th>\n",
+       "      <td>-1.433570</td>\n",
+       "      <td>0.714861</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>1</th>\n",
+       "      <td>-0.600733</td>\n",
+       "      <td>2.744446</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>2</th>\n",
+       "      <td>0.622874</td>\n",
+       "      <td>1.816995</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>3</th>\n",
+       "      <td>1.879785</td>\n",
+       "      <td>4.981217</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>2.477957</td>\n",
+       "      <td>5.932101</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>...</th>\n",
+       "      <th>...</th>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"5\" valign=\"top\">99</th>\n",
+       "      <th>12</th>\n",
+       "      <td>10.736462</td>\n",
+       "      <td>13.415872</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>13</th>\n",
+       "      <td>11.617465</td>\n",
+       "      <td>15.103293</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>14</th>\n",
+       "      <td>12.858327</td>\n",
+       "      <td>16.105966</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>15</th>\n",
+       "      <td>13.652358</td>\n",
+       "      <td>16.148926</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>16</th>\n",
+       "      <td>14.442286</td>\n",
+       "      <td>17.567963</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "<p>1547 rows × 2 columns</p>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "TimeSeriesSamples with data:\n",
+       "                             0          1\n",
+       "sample_idx time_idx                      \n",
+       "0          0         -1.433570   0.714861\n",
+       "           1         -0.600733   2.744446\n",
+       "           2          0.622874   1.816995\n",
+       "           3          1.879785   4.981217\n",
+       "           4          2.477957   5.932101\n",
+       "...                        ...        ...\n",
+       "99         12        10.736462  13.415872\n",
+       "           13        11.617465  15.103293\n",
+       "           14        12.858327  16.105966\n",
+       "           15        13.652358  16.148926\n",
+       "           16        14.442286  17.567963\n",
+       "\n",
+       "[1547 rows x 2 columns]"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "predictive.treatments:\n"
+     ]
+    },
+    {
+     "data": {
+      "text/html": [
+       "<p><span style=\"font-family: monospace;\">TimeSeriesSamples</span> with data:</p><div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th>0</th>\n",
+       "      <th>1</th>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_idx</th>\n",
+       "      <th>time_idx</th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"5\" valign=\"top\">0</th>\n",
+       "      <th>0</th>\n",
+       "      <td>-1.433570</td>\n",
+       "      <td>0.714861</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>1</th>\n",
+       "      <td>-0.600733</td>\n",
+       "      <td>2.744446</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>2</th>\n",
+       "      <td>0.622874</td>\n",
+       "      <td>1.816995</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>3</th>\n",
+       "      <td>1.879785</td>\n",
+       "      <td>4.981217</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>2.477957</td>\n",
+       "      <td>5.932101</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>...</th>\n",
+       "      <th>...</th>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"5\" valign=\"top\">99</th>\n",
+       "      <th>12</th>\n",
+       "      <td>10.736462</td>\n",
+       "      <td>13.415872</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>13</th>\n",
+       "      <td>11.617465</td>\n",
+       "      <td>15.103293</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>14</th>\n",
+       "      <td>12.858327</td>\n",
+       "      <td>16.105966</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>15</th>\n",
+       "      <td>13.652358</td>\n",
+       "      <td>16.148926</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>16</th>\n",
+       "      <td>14.442286</td>\n",
+       "      <td>17.567963</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "<p>1547 rows × 2 columns</p>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "TimeSeriesSamples with data:\n",
+       "                             0          1\n",
+       "sample_idx time_idx                      \n",
+       "0          0         -1.433570   0.714861\n",
+       "           1         -0.600733   2.744446\n",
+       "           2          0.622874   1.816995\n",
+       "           3          1.879785   4.981217\n",
+       "           4          2.477957   5.932101\n",
+       "...                        ...        ...\n",
+       "99         12        10.736462  13.415872\n",
+       "           13        11.617465  15.103293\n",
+       "           14        12.858327  16.105966\n",
+       "           15        13.652358  16.148926\n",
+       "           16        14.442286  17.567963\n",
+       "\n",
+       "[1547 rows x 2 columns]"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "\n",
+      "--------------------------------------------------------------------------------\n",
+      "\n",
+      "GoogleStocksDataLoader loads the following dataset:\n",
+      "\n",
+      "OneOffPredictionDataset(\n",
+      "    time_series=TimeSeriesSamples([50, *, 5]),\n",
+      "    predictive=OneOffPredictionTaskData(targets=StaticSamples([50, 1]))\n",
+      ")\n",
+      "This contains:\n",
+      "\n",
+      "time_series:\n"
+     ]
+    },
+    {
+     "data": {
+      "text/html": [
+       "<p><span style=\"font-family: monospace;\">TimeSeriesSamples</span> with data:</p><div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th>Open</th>\n",
+       "      <th>High</th>\n",
+       "      <th>Low</th>\n",
+       "      <th>Close</th>\n",
+       "      <th>Volume</th>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_idx</th>\n",
+       "      <th>time_idx</th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"5\" valign=\"top\">0</th>\n",
+       "      <th>0.875000</th>\n",
+       "      <td>0.661264</td>\n",
+       "      <td>0.652789</td>\n",
+       "      <td>0.677836</td>\n",
+       "      <td>0.696887</td>\n",
+       "      <td>0.185147</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>0.886364</th>\n",
+       "      <td>0.667446</td>\n",
+       "      <td>0.716935</td>\n",
+       "      <td>0.731552</td>\n",
+       "      <td>0.748318</td>\n",
+       "      <td>0.150912</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>0.897727</th>\n",
+       "      <td>0.751374</td>\n",
+       "      <td>0.784055</td>\n",
+       "      <td>0.800261</td>\n",
+       "      <td>0.791407</td>\n",
+       "      <td>0.140203</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>0.909091</th>\n",
+       "      <td>0.785577</td>\n",
+       "      <td>0.838572</td>\n",
+       "      <td>0.831813</td>\n",
+       "      <td>0.832628</td>\n",
+       "      <td>0.244291</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>0.920455</th>\n",
+       "      <td>0.885578</td>\n",
+       "      <td>0.879778</td>\n",
+       "      <td>0.900782</td>\n",
+       "      <td>0.889539</td>\n",
+       "      <td>0.413625</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>...</th>\n",
+       "      <th>...</th>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"5\" valign=\"top\">9</th>\n",
+       "      <th>0.806818</th>\n",
+       "      <td>0.642857</td>\n",
+       "      <td>0.647974</td>\n",
+       "      <td>0.649153</td>\n",
+       "      <td>0.639975</td>\n",
+       "      <td>0.625178</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>0.818182</th>\n",
+       "      <td>0.687362</td>\n",
+       "      <td>0.757221</td>\n",
+       "      <td>0.741200</td>\n",
+       "      <td>0.789788</td>\n",
+       "      <td>0.333141</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>0.829545</th>\n",
+       "      <td>0.756044</td>\n",
+       "      <td>0.732512</td>\n",
+       "      <td>0.772230</td>\n",
+       "      <td>0.732379</td>\n",
+       "      <td>0.120629</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>0.840909</th>\n",
+       "      <td>0.710852</td>\n",
+       "      <td>0.687907</td>\n",
+       "      <td>0.721525</td>\n",
+       "      <td>0.713076</td>\n",
+       "      <td>0.101900</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>0.875000</th>\n",
+       "      <td>0.661264</td>\n",
+       "      <td>0.652789</td>\n",
+       "      <td>0.677836</td>\n",
+       "      <td>0.696887</td>\n",
+       "      <td>0.185147</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "<p>500 rows × 5 columns</p>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "TimeSeriesSamples with data:\n",
+       "                         Open      High       Low     Close    Volume\n",
+       "sample_idx time_idx                                                  \n",
+       "0          0.875000  0.661264  0.652789  0.677836  0.696887  0.185147\n",
+       "           0.886364  0.667446  0.716935  0.731552  0.748318  0.150912\n",
+       "           0.897727  0.751374  0.784055  0.800261  0.791407  0.140203\n",
+       "           0.909091  0.785577  0.838572  0.831813  0.832628  0.244291\n",
+       "           0.920455  0.885578  0.879778  0.900782  0.889539  0.413625\n",
+       "...                       ...       ...       ...       ...       ...\n",
+       "9          0.806818  0.642857  0.647974  0.649153  0.639975  0.625178\n",
+       "           0.818182  0.687362  0.757221  0.741200  0.789788  0.333141\n",
+       "           0.829545  0.756044  0.732512  0.772230  0.732379  0.120629\n",
+       "           0.840909  0.710852  0.687907  0.721525  0.713076  0.101900\n",
+       "           0.875000  0.661264  0.652789  0.677836  0.696887  0.185147\n",
+       "\n",
+       "[500 rows x 5 columns]"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "predictive.targets:\n"
+     ]
+    },
+    {
+     "data": {
+      "text/html": [
+       "<p><span style=\"font-family: monospace;\">StaticSamples</span> with data:</p><div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th>out</th>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_idx</th>\n",
+       "      <th></th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th>0</th>\n",
+       "      <td>0.710852</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>1</th>\n",
+       "      <td>0.756044</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>10</th>\n",
+       "      <td>0.564835</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>11</th>\n",
+       "      <td>0.557005</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>12</th>\n",
+       "      <td>0.552061</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>13</th>\n",
+       "      <td>0.510852</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>14</th>\n",
+       "      <td>0.451786</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>15</th>\n",
+       "      <td>0.421704</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>16</th>\n",
+       "      <td>0.387225</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>17</th>\n",
+       "      <td>0.345879</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>18</th>\n",
+       "      <td>0.286951</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>19</th>\n",
+       "      <td>0.332143</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>2</th>\n",
+       "      <td>0.687362</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>20</th>\n",
+       "      <td>0.205906</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>21</th>\n",
+       "      <td>0.286676</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>22</th>\n",
+       "      <td>0.247939</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>23</th>\n",
+       "      <td>0.492445</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>24</th>\n",
+       "      <td>0.767858</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>25</th>\n",
+       "      <td>0.810440</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>26</th>\n",
+       "      <td>0.697940</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>27</th>\n",
+       "      <td>0.597390</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>28</th>\n",
+       "      <td>0.390659</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>29</th>\n",
+       "      <td>0.385989</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>3</th>\n",
+       "      <td>0.642857</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>30</th>\n",
+       "      <td>0.361401</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>31</th>\n",
+       "      <td>0.370879</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>32</th>\n",
+       "      <td>0.388325</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>33</th>\n",
+       "      <td>0.393819</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>34</th>\n",
+       "      <td>0.389149</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>35</th>\n",
+       "      <td>0.359753</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>36</th>\n",
+       "      <td>0.399038</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>37</th>\n",
+       "      <td>0.378984</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>38</th>\n",
+       "      <td>0.225962</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>39</th>\n",
+       "      <td>0.099863</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>0.628297</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>40</th>\n",
+       "      <td>0.131181</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>41</th>\n",
+       "      <td>0.000000</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>42</th>\n",
+       "      <td>0.054121</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>43</th>\n",
+       "      <td>0.062088</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>44</th>\n",
+       "      <td>0.204533</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>45</th>\n",
+       "      <td>0.163049</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>46</th>\n",
+       "      <td>0.166072</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>47</th>\n",
+       "      <td>0.186126</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>48</th>\n",
+       "      <td>0.233929</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>49</th>\n",
+       "      <td>0.246566</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>5</th>\n",
+       "      <td>0.671978</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>6</th>\n",
+       "      <td>0.704808</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>7</th>\n",
+       "      <td>0.684753</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>8</th>\n",
+       "      <td>0.684753</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>9</th>\n",
+       "      <td>0.607281</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "StaticSamples with data:\n",
+       "                 out\n",
+       "sample_idx          \n",
+       "0           0.710852\n",
+       "1           0.756044\n",
+       "10          0.564835\n",
+       "11          0.557005\n",
+       "12          0.552061\n",
+       "13          0.510852\n",
+       "14          0.451786\n",
+       "15          0.421704\n",
+       "16          0.387225\n",
+       "17          0.345879\n",
+       "18          0.286951\n",
+       "19          0.332143\n",
+       "2           0.687362\n",
+       "20          0.205906\n",
+       "21          0.286676\n",
+       "22          0.247939\n",
+       "23          0.492445\n",
+       "24          0.767858\n",
+       "25          0.810440\n",
+       "26          0.697940\n",
+       "27          0.597390\n",
+       "28          0.390659\n",
+       "29          0.385989\n",
+       "3           0.642857\n",
+       "30          0.361401\n",
+       "31          0.370879\n",
+       "32          0.388325\n",
+       "33          0.393819\n",
+       "34          0.389149\n",
+       "35          0.359753\n",
+       "36          0.399038\n",
+       "37          0.378984\n",
+       "38          0.225962\n",
+       "39          0.099863\n",
+       "4           0.628297\n",
+       "40          0.131181\n",
+       "41          0.000000\n",
+       "42          0.054121\n",
+       "43          0.062088\n",
+       "44          0.204533\n",
+       "45          0.163049\n",
+       "46          0.166072\n",
+       "47          0.186126\n",
+       "48          0.233929\n",
+       "49          0.246566\n",
+       "5           0.671978\n",
+       "6           0.704808\n",
+       "7           0.684753\n",
+       "8           0.684753\n",
+       "9           0.607281"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "\n",
+      "--------------------------------------------------------------------------------\n",
+      "\n",
+      "PBCDataLoader loads the following dataset:\n",
+      "\n",
+      "TimeToEventAnalysisDataset(\n",
+      "    time_series=TimeSeriesSamples([312, *, 14]),\n",
+      "    static=StaticSamples([312, 1]),\n",
+      "    predictive=TimeToEventAnalysisTaskData(targets=EventSamples([312, 1]))\n",
+      ")\n",
+      "This contains:\n",
+      "\n",
+      "time_series:\n"
+     ]
+    },
+    {
+     "data": {
+      "text/html": [
+       "<p><span style=\"font-family: monospace;\">TimeSeriesSamples</span> with data:</p><div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th>drug</th>\n",
+       "      <th>ascites</th>\n",
+       "      <th>hepatomegaly</th>\n",
+       "      <th>spiders</th>\n",
+       "      <th>edema</th>\n",
+       "      <th>histologic</th>\n",
+       "      <th>serBilir</th>\n",
+       "      <th>serChol</th>\n",
+       "      <th>albumin</th>\n",
+       "      <th>alkaline</th>\n",
+       "      <th>SGOT</th>\n",
+       "      <th>platelets</th>\n",
+       "      <th>prothrombin</th>\n",
+       "      <th>age</th>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_idx</th>\n",
+       "      <th>time_idx</th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"2\" valign=\"top\">1</th>\n",
+       "      <th>0.569489</th>\n",
+       "      <td>0.0</td>\n",
+       "      <td>1.0</td>\n",
+       "      <td>1.0</td>\n",
+       "      <td>1.0</td>\n",
+       "      <td>1.0</td>\n",
+       "      <td>3.0</td>\n",
+       "      <td>3.281890</td>\n",
+       "      <td>0.000000</td>\n",
+       "      <td>-0.894575</td>\n",
+       "      <td>0.195532</td>\n",
+       "      <td>-1.485263</td>\n",
+       "      <td>-0.529101</td>\n",
+       "      <td>0.136768</td>\n",
+       "      <td>0.248058</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>1.095170</th>\n",
+       "      <td>0.0</td>\n",
+       "      <td>1.0</td>\n",
+       "      <td>1.0</td>\n",
+       "      <td>1.0</td>\n",
+       "      <td>1.0</td>\n",
+       "      <td>3.0</td>\n",
+       "      <td>2.015877</td>\n",
+       "      <td>-0.469461</td>\n",
+       "      <td>-1.570646</td>\n",
+       "      <td>0.285613</td>\n",
+       "      <td>0.195488</td>\n",
+       "      <td>-0.456022</td>\n",
+       "      <td>0.813132</td>\n",
+       "      <td>0.248058</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"3\" valign=\"top\">2</th>\n",
+       "      <th>5.319790</th>\n",
+       "      <td>0.0</td>\n",
+       "      <td>1.0</td>\n",
+       "      <td>1.0</td>\n",
+       "      <td>1.0</td>\n",
+       "      <td>1.0</td>\n",
+       "      <td>2.0</td>\n",
+       "      <td>0.172710</td>\n",
+       "      <td>-0.658914</td>\n",
+       "      <td>-1.431455</td>\n",
+       "      <td>-0.605844</td>\n",
+       "      <td>-0.442126</td>\n",
+       "      <td>-1.395605</td>\n",
+       "      <td>0.339677</td>\n",
+       "      <td>1.292856</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>6.261636</th>\n",
+       "      <td>0.0</td>\n",
+       "      <td>1.0</td>\n",
+       "      <td>1.0</td>\n",
+       "      <td>1.0</td>\n",
+       "      <td>1.0</td>\n",
+       "      <td>2.0</td>\n",
+       "      <td>-0.013468</td>\n",
+       "      <td>-0.603657</td>\n",
+       "      <td>-1.172958</td>\n",
+       "      <td>-0.512364</td>\n",
+       "      <td>-0.046806</td>\n",
+       "      <td>-1.259888</td>\n",
+       "      <td>0.339677</td>\n",
+       "      <td>1.292856</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>7.266455</th>\n",
+       "      <td>0.0</td>\n",
+       "      <td>1.0</td>\n",
+       "      <td>1.0</td>\n",
+       "      <td>1.0</td>\n",
+       "      <td>1.0</td>\n",
+       "      <td>2.0</td>\n",
+       "      <td>0.098239</td>\n",
+       "      <td>0.000000</td>\n",
+       "      <td>-1.312149</td>\n",
+       "      <td>-0.443529</td>\n",
+       "      <td>0.293680</td>\n",
+       "      <td>-1.364286</td>\n",
+       "      <td>0.339677</td>\n",
+       "      <td>1.292856</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>...</th>\n",
+       "      <th>...</th>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"5\" valign=\"top\">312</th>\n",
+       "      <th>1.045888</th>\n",
+       "      <td>1.0</td>\n",
+       "      <td>0.0</td>\n",
+       "      <td>0.0</td>\n",
+       "      <td>1.0</td>\n",
+       "      <td>2.0</td>\n",
+       "      <td>2.0</td>\n",
+       "      <td>3.672865</td>\n",
+       "      <td>3.319599</td>\n",
+       "      <td>0.059878</td>\n",
+       "      <td>1.385274</td>\n",
+       "      <td>0.986129</td>\n",
+       "      <td>-1.103291</td>\n",
+       "      <td>1.624769</td>\n",
+       "      <td>-1.962482</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>1.867265</th>\n",
+       "      <td>1.0</td>\n",
+       "      <td>0.0</td>\n",
+       "      <td>0.0</td>\n",
+       "      <td>1.0</td>\n",
+       "      <td>2.0</td>\n",
+       "      <td>1.0</td>\n",
+       "      <td>2.350998</td>\n",
+       "      <td>2.901224</td>\n",
+       "      <td>-0.099197</td>\n",
+       "      <td>0.916176</td>\n",
+       "      <td>0.641817</td>\n",
+       "      <td>-0.998892</td>\n",
+       "      <td>1.354223</td>\n",
+       "      <td>-1.962482</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>2.921367</th>\n",
+       "      <td>1.0</td>\n",
+       "      <td>0.0</td>\n",
+       "      <td>0.0</td>\n",
+       "      <td>0.0</td>\n",
+       "      <td>0.0</td>\n",
+       "      <td>1.0</td>\n",
+       "      <td>0.694010</td>\n",
+       "      <td>-0.066873</td>\n",
+       "      <td>0.338261</td>\n",
+       "      <td>0.327254</td>\n",
+       "      <td>0.552551</td>\n",
+       "      <td>-0.894494</td>\n",
+       "      <td>0.474950</td>\n",
+       "      <td>-1.962482</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>3.425145</th>\n",
+       "      <td>1.0</td>\n",
+       "      <td>0.0</td>\n",
+       "      <td>0.0</td>\n",
+       "      <td>0.0</td>\n",
+       "      <td>0.0</td>\n",
+       "      <td>1.0</td>\n",
+       "      <td>0.340271</td>\n",
+       "      <td>0.000000</td>\n",
+       "      <td>-0.377580</td>\n",
+       "      <td>0.251620</td>\n",
+       "      <td>0.016956</td>\n",
+       "      <td>-0.466462</td>\n",
+       "      <td>-0.066141</td>\n",
+       "      <td>-1.962482</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>3.989158</th>\n",
+       "      <td>1.0</td>\n",
+       "      <td>0.0</td>\n",
+       "      <td>0.0</td>\n",
+       "      <td>1.0</td>\n",
+       "      <td>0.0</td>\n",
+       "      <td>1.0</td>\n",
+       "      <td>0.507832</td>\n",
+       "      <td>2.017110</td>\n",
+       "      <td>0.795603</td>\n",
+       "      <td>0.622990</td>\n",
+       "      <td>0.169983</td>\n",
+       "      <td>-0.351624</td>\n",
+       "      <td>-0.133778</td>\n",
+       "      <td>-1.962482</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "<p>1945 rows × 14 columns</p>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "TimeSeriesSamples with data:\n",
+       "                     drug  ascites  hepatomegaly  spiders  edema  histologic   \n",
+       "sample_idx time_idx                                                            \n",
+       "1          0.569489   0.0      1.0           1.0      1.0    1.0         3.0  \\\n",
+       "           1.095170   0.0      1.0           1.0      1.0    1.0         3.0   \n",
+       "2          5.319790   0.0      1.0           1.0      1.0    1.0         2.0   \n",
+       "           6.261636   0.0      1.0           1.0      1.0    1.0         2.0   \n",
+       "           7.266455   0.0      1.0           1.0      1.0    1.0         2.0   \n",
+       "...                   ...      ...           ...      ...    ...         ...   \n",
+       "312        1.045888   1.0      0.0           0.0      1.0    2.0         2.0   \n",
+       "           1.867265   1.0      0.0           0.0      1.0    2.0         1.0   \n",
+       "           2.921367   1.0      0.0           0.0      0.0    0.0         1.0   \n",
+       "           3.425145   1.0      0.0           0.0      0.0    0.0         1.0   \n",
+       "           3.989158   1.0      0.0           0.0      1.0    0.0         1.0   \n",
+       "\n",
+       "                     serBilir   serChol   albumin  alkaline      SGOT   \n",
+       "sample_idx time_idx                                                     \n",
+       "1          0.569489  3.281890  0.000000 -0.894575  0.195532 -1.485263  \\\n",
+       "           1.095170  2.015877 -0.469461 -1.570646  0.285613  0.195488   \n",
+       "2          5.319790  0.172710 -0.658914 -1.431455 -0.605844 -0.442126   \n",
+       "           6.261636 -0.013468 -0.603657 -1.172958 -0.512364 -0.046806   \n",
+       "           7.266455  0.098239  0.000000 -1.312149 -0.443529  0.293680   \n",
+       "...                       ...       ...       ...       ...       ...   \n",
+       "312        1.045888  3.672865  3.319599  0.059878  1.385274  0.986129   \n",
+       "           1.867265  2.350998  2.901224 -0.099197  0.916176  0.641817   \n",
+       "           2.921367  0.694010 -0.066873  0.338261  0.327254  0.552551   \n",
+       "           3.425145  0.340271  0.000000 -0.377580  0.251620  0.016956   \n",
+       "           3.989158  0.507832  2.017110  0.795603  0.622990  0.169983   \n",
+       "\n",
+       "                     platelets  prothrombin       age  \n",
+       "sample_idx time_idx                                    \n",
+       "1          0.569489  -0.529101     0.136768  0.248058  \n",
+       "           1.095170  -0.456022     0.813132  0.248058  \n",
+       "2          5.319790  -1.395605     0.339677  1.292856  \n",
+       "           6.261636  -1.259888     0.339677  1.292856  \n",
+       "           7.266455  -1.364286     0.339677  1.292856  \n",
+       "...                        ...          ...       ...  \n",
+       "312        1.045888  -1.103291     1.624769 -1.962482  \n",
+       "           1.867265  -0.998892     1.354223 -1.962482  \n",
+       "           2.921367  -0.894494     0.474950 -1.962482  \n",
+       "           3.425145  -0.466462    -0.066141 -1.962482  \n",
+       "           3.989158  -0.351624    -0.133778 -1.962482  \n",
+       "\n",
+       "[1945 rows x 14 columns]"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "static:\n"
+     ]
+    },
+    {
+     "data": {
+      "text/html": [
+       "<p><span style=\"font-family: monospace;\">StaticSamples</span> with data:</p><div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th>sex</th>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_idx</th>\n",
+       "      <th></th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th>1</th>\n",
+       "      <td>0.0</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>2</th>\n",
+       "      <td>0.0</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>3</th>\n",
+       "      <td>1.0</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>0.0</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>5</th>\n",
+       "      <td>0.0</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>...</th>\n",
+       "      <td>...</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>308</th>\n",
+       "      <td>0.0</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>309</th>\n",
+       "      <td>0.0</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>310</th>\n",
+       "      <td>0.0</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>311</th>\n",
+       "      <td>0.0</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>312</th>\n",
+       "      <td>0.0</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "<p>312 rows × 1 columns</p>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "StaticSamples with data:\n",
+       "            sex\n",
+       "sample_idx     \n",
+       "1           0.0\n",
+       "2           0.0\n",
+       "3           1.0\n",
+       "4           0.0\n",
+       "5           0.0\n",
+       "...         ...\n",
+       "308         0.0\n",
+       "309         0.0\n",
+       "310         0.0\n",
+       "311         0.0\n",
+       "312         0.0\n",
+       "\n",
+       "[312 rows x 1 columns]"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "predictive.targets:\n"
+     ]
+    },
+    {
+     "data": {
+      "text/html": [
+       "<p><span style=\"font-family: monospace;\">EventSamples</span> with data:</p><div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th>status</th>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_idx</th>\n",
+       "      <th></th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th>1</th>\n",
+       "      <td>(0.569488555470374, True)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>2</th>\n",
+       "      <td>(14.1523381885883, False)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>3</th>\n",
+       "      <td>(0.7365020260650499, True)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>(0.27653050049282957, True)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>5</th>\n",
+       "      <td>(4.12057824991786, False)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>...</th>\n",
+       "      <td>...</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>308</th>\n",
+       "      <td>(4.98850071186069, False)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>309</th>\n",
+       "      <td>(4.55317051801555, False)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>310</th>\n",
+       "      <td>(4.4025846019056, False)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>311</th>\n",
+       "      <td>(4.12879202716022, False)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>312</th>\n",
+       "      <td>(3.98915781404008, False)</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "<p>312 rows × 1 columns</p>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "EventSamples with data:\n",
+       "                                 status\n",
+       "sample_idx                             \n",
+       "1             (0.569488555470374, True)\n",
+       "2             (14.1523381885883, False)\n",
+       "3            (0.7365020260650499, True)\n",
+       "4           (0.27653050049282957, True)\n",
+       "5             (4.12057824991786, False)\n",
+       "...                                 ...\n",
+       "308           (4.98850071186069, False)\n",
+       "309           (4.55317051801555, False)\n",
+       "310            (4.4025846019056, False)\n",
+       "311           (4.12879202716022, False)\n",
+       "312           (3.98915781404008, False)\n",
+       "\n",
+       "[312 rows x 1 columns]"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "\n",
+      "--------------------------------------------------------------------------------\n",
+      "\n",
+      "PKPDDataLoader loads the following dataset:\n",
+      "\n",
+      "Generating simple PKPD dataset with random seed 100...\n",
+      "OneOffTreatmentEffectsDataset(\n",
+      "    time_series=TimeSeriesSamples([40, *, 2]),\n",
+      "    predictive=OneOffTreatmentEffectsTaskData(\n",
+      "        targets=TimeSeriesSamples([40, *, 1]),\n",
+      "        treatments=EventSamples([40, 1])\n",
+      "    )\n",
+      ")\n",
+      "This contains:\n",
+      "\n",
+      "time_series:\n"
+     ]
+    },
+    {
+     "data": {
+      "text/html": [
+       "<p><span style=\"font-family: monospace;\">TimeSeriesSamples</span> with data:</p><div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th>k_in</th>\n",
+       "      <th>p</th>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_idx</th>\n",
+       "      <th>time_idx</th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"5\" valign=\"top\">0</th>\n",
+       "      <th>0</th>\n",
+       "      <td>-0.781441</td>\n",
+       "      <td>-0.245827</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>1</th>\n",
+       "      <td>-1.001889</td>\n",
+       "      <td>-0.541524</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>2</th>\n",
+       "      <td>-1.070862</td>\n",
+       "      <td>-0.589326</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>3</th>\n",
+       "      <td>-1.425115</td>\n",
+       "      <td>-1.065485</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>-1.841006</td>\n",
+       "      <td>-1.542429</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>...</th>\n",
+       "      <th>...</th>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"5\" valign=\"top\">39</th>\n",
+       "      <th>5</th>\n",
+       "      <td>0.959902</td>\n",
+       "      <td>-0.690057</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>6</th>\n",
+       "      <td>1.683426</td>\n",
+       "      <td>-0.128967</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>7</th>\n",
+       "      <td>2.233045</td>\n",
+       "      <td>0.637906</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>8</th>\n",
+       "      <td>1.645018</td>\n",
+       "      <td>1.056963</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>9</th>\n",
+       "      <td>0.333051</td>\n",
+       "      <td>1.048721</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "<p>400 rows × 2 columns</p>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "TimeSeriesSamples with data:\n",
+       "                         k_in         p\n",
+       "sample_idx time_idx                    \n",
+       "0          0        -0.781441 -0.245827\n",
+       "           1        -1.001889 -0.541524\n",
+       "           2        -1.070862 -0.589326\n",
+       "           3        -1.425115 -1.065485\n",
+       "           4        -1.841006 -1.542429\n",
+       "...                       ...       ...\n",
+       "39         5         0.959902 -0.690057\n",
+       "           6         1.683426 -0.128967\n",
+       "           7         2.233045  0.637906\n",
+       "           8         1.645018  1.056963\n",
+       "           9         0.333051  1.048721\n",
+       "\n",
+       "[400 rows x 2 columns]"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "predictive.targets:\n"
+     ]
+    },
+    {
+     "data": {
+      "text/html": [
+       "<p><span style=\"font-family: monospace;\">TimeSeriesSamples</span> with data:</p><div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th>y</th>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_idx</th>\n",
+       "      <th>time_idx</th>\n",
+       "      <th></th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"5\" valign=\"top\">0</th>\n",
+       "      <th>0</th>\n",
+       "      <td>-0.197049</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>1</th>\n",
+       "      <td>0.020346</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>2</th>\n",
+       "      <td>-0.281120</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>3</th>\n",
+       "      <td>-0.483934</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>-0.947253</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>...</th>\n",
+       "      <th>...</th>\n",
+       "      <td>...</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"5\" valign=\"top\">39</th>\n",
+       "      <th>5</th>\n",
+       "      <td>-1.418583</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>6</th>\n",
+       "      <td>-1.495843</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>7</th>\n",
+       "      <td>-1.193632</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>8</th>\n",
+       "      <td>-0.850845</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>9</th>\n",
+       "      <td>-0.431988</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "<p>400 rows × 1 columns</p>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "TimeSeriesSamples with data:\n",
+       "                            y\n",
+       "sample_idx time_idx          \n",
+       "0          0        -0.197049\n",
+       "           1         0.020346\n",
+       "           2        -0.281120\n",
+       "           3        -0.483934\n",
+       "           4        -0.947253\n",
+       "...                       ...\n",
+       "39         5        -1.418583\n",
+       "           6        -1.495843\n",
+       "           7        -1.193632\n",
+       "           8        -0.850845\n",
+       "           9        -0.431988\n",
+       "\n",
+       "[400 rows x 1 columns]"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "predictive.treatments:\n"
+     ]
+    },
+    {
+     "data": {
+      "text/html": [
+       "<p><span style=\"font-family: monospace;\">EventSamples</span> with data:</p><div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th>a</th>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_idx</th>\n",
+       "      <th></th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th>0</th>\n",
+       "      <td>(7, False)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>1</th>\n",
+       "      <td>(7, False)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>2</th>\n",
+       "      <td>(7, False)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>3</th>\n",
+       "      <td>(7, False)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>(7, False)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>5</th>\n",
+       "      <td>(7, False)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>6</th>\n",
+       "      <td>(7, False)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>7</th>\n",
+       "      <td>(7, False)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>8</th>\n",
+       "      <td>(7, False)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>9</th>\n",
+       "      <td>(7, False)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>10</th>\n",
+       "      <td>(7, False)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>11</th>\n",
+       "      <td>(7, False)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>12</th>\n",
+       "      <td>(7, False)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>13</th>\n",
+       "      <td>(7, False)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>14</th>\n",
+       "      <td>(7, False)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>15</th>\n",
+       "      <td>(7, False)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>16</th>\n",
+       "      <td>(7, False)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>17</th>\n",
+       "      <td>(7, False)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>18</th>\n",
+       "      <td>(7, False)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>19</th>\n",
+       "      <td>(7, False)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>20</th>\n",
+       "      <td>(7, True)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>21</th>\n",
+       "      <td>(7, True)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>22</th>\n",
+       "      <td>(7, True)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>23</th>\n",
+       "      <td>(7, True)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>24</th>\n",
+       "      <td>(7, True)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>25</th>\n",
+       "      <td>(7, True)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>26</th>\n",
+       "      <td>(7, True)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>27</th>\n",
+       "      <td>(7, True)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>28</th>\n",
+       "      <td>(7, True)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>29</th>\n",
+       "      <td>(7, True)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>30</th>\n",
+       "      <td>(7, True)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>31</th>\n",
+       "      <td>(7, True)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>32</th>\n",
+       "      <td>(7, True)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>33</th>\n",
+       "      <td>(7, True)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>34</th>\n",
+       "      <td>(7, True)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>35</th>\n",
+       "      <td>(7, True)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>36</th>\n",
+       "      <td>(7, True)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>37</th>\n",
+       "      <td>(7, True)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>38</th>\n",
+       "      <td>(7, True)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>39</th>\n",
+       "      <td>(7, True)</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "EventSamples with data:\n",
+       "                     a\n",
+       "sample_idx            \n",
+       "0           (7, False)\n",
+       "1           (7, False)\n",
+       "2           (7, False)\n",
+       "3           (7, False)\n",
+       "4           (7, False)\n",
+       "5           (7, False)\n",
+       "6           (7, False)\n",
+       "7           (7, False)\n",
+       "8           (7, False)\n",
+       "9           (7, False)\n",
+       "10          (7, False)\n",
+       "11          (7, False)\n",
+       "12          (7, False)\n",
+       "13          (7, False)\n",
+       "14          (7, False)\n",
+       "15          (7, False)\n",
+       "16          (7, False)\n",
+       "17          (7, False)\n",
+       "18          (7, False)\n",
+       "19          (7, False)\n",
+       "20           (7, True)\n",
+       "21           (7, True)\n",
+       "22           (7, True)\n",
+       "23           (7, True)\n",
+       "24           (7, True)\n",
+       "25           (7, True)\n",
+       "26           (7, True)\n",
+       "27           (7, True)\n",
+       "28           (7, True)\n",
+       "29           (7, True)\n",
+       "30           (7, True)\n",
+       "31           (7, True)\n",
+       "32           (7, True)\n",
+       "33           (7, True)\n",
+       "34           (7, True)\n",
+       "35           (7, True)\n",
+       "36           (7, True)\n",
+       "37           (7, True)\n",
+       "38           (7, True)\n",
+       "39           (7, True)"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "\n",
+      "--------------------------------------------------------------------------------\n",
+      "\n",
+      "SineDataLoader loads the following dataset:\n",
+      "\n",
+      "OneOffPredictionDataset(\n",
+      "    time_series=TimeSeriesSamples([100, *, 5]),\n",
+      "    static=StaticSamples([100, 4]),\n",
+      "    predictive=OneOffPredictionTaskData(targets=StaticSamples([100, 1]))\n",
+      ")\n",
+      "This contains:\n",
+      "\n",
+      "time_series:\n"
+     ]
+    },
+    {
+     "data": {
+      "text/html": [
+       "<p><span style=\"font-family: monospace;\">TimeSeriesSamples</span> with data:</p><div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th>0</th>\n",
+       "      <th>1</th>\n",
+       "      <th>2</th>\n",
+       "      <th>3</th>\n",
+       "      <th>4</th>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_idx</th>\n",
+       "      <th>time_idx</th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"5\" valign=\"top\">0</th>\n",
+       "      <th>0</th>\n",
+       "      <td>-0.019015</td>\n",
+       "      <td>-0.048177</td>\n",
+       "      <td>-0.108546</td>\n",
+       "      <td>0.441865</td>\n",
+       "      <td>0.024508</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>1</th>\n",
+       "      <td>0.300030</td>\n",
+       "      <td>0.364550</td>\n",
+       "      <td>0.576590</td>\n",
+       "      <td>0.890053</td>\n",
+       "      <td>0.534722</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>2</th>\n",
+       "      <td>0.587904</td>\n",
+       "      <td>0.713509</td>\n",
+       "      <td>0.972993</td>\n",
+       "      <td>0.986179</td>\n",
+       "      <td>0.892946</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>3</th>\n",
+       "      <td>0.814697</td>\n",
+       "      <td>0.937661</td>\n",
+       "      <td>0.882158</td>\n",
+       "      <td>0.692221</td>\n",
+       "      <td>0.997357</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>0.956846</td>\n",
+       "      <td>0.997797</td>\n",
+       "      <td>0.349572</td>\n",
+       "      <td>0.124454</td>\n",
+       "      <td>0.818278</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>...</th>\n",
+       "      <th>...</th>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"5\" valign=\"top\">99</th>\n",
+       "      <th>5</th>\n",
+       "      <td>0.967121</td>\n",
+       "      <td>0.126890</td>\n",
+       "      <td>0.926979</td>\n",
+       "      <td>0.982022</td>\n",
+       "      <td>0.963113</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>6</th>\n",
+       "      <td>0.706533</td>\n",
+       "      <td>0.413329</td>\n",
+       "      <td>0.569034</td>\n",
+       "      <td>0.656214</td>\n",
+       "      <td>0.989224</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>7</th>\n",
+       "      <td>0.252748</td>\n",
+       "      <td>0.663121</td>\n",
+       "      <td>0.024381</td>\n",
+       "      <td>0.050668</td>\n",
+       "      <td>0.999771</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>8</th>\n",
+       "      <td>-0.270150</td>\n",
+       "      <td>0.854119</td>\n",
+       "      <td>-0.528273</td>\n",
+       "      <td>-0.576478</td>\n",
+       "      <td>0.994586</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>9</th>\n",
+       "      <td>-0.719177</td>\n",
+       "      <td>0.969389</td>\n",
+       "      <td>-0.907592</td>\n",
+       "      <td>-0.957876</td>\n",
+       "      <td>0.973752</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "<p>1000 rows × 5 columns</p>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "TimeSeriesSamples with data:\n",
+       "                            0         1         2         3         4\n",
+       "sample_idx time_idx                                                  \n",
+       "0          0        -0.019015 -0.048177 -0.108546  0.441865  0.024508\n",
+       "           1         0.300030  0.364550  0.576590  0.890053  0.534722\n",
+       "           2         0.587904  0.713509  0.972993  0.986179  0.892946\n",
+       "           3         0.814697  0.937661  0.882158  0.692221  0.997357\n",
+       "           4         0.956846  0.997797  0.349572  0.124454  0.818278\n",
+       "...                       ...       ...       ...       ...       ...\n",
+       "99         5         0.967121  0.126890  0.926979  0.982022  0.963113\n",
+       "           6         0.706533  0.413329  0.569034  0.656214  0.989224\n",
+       "           7         0.252748  0.663121  0.024381  0.050668  0.999771\n",
+       "           8        -0.270150  0.854119 -0.528273 -0.576478  0.994586\n",
+       "           9        -0.719177  0.969389 -0.907592 -0.957876  0.973752\n",
+       "\n",
+       "[1000 rows x 5 columns]"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "static:\n"
+     ]
+    },
+    {
+     "data": {
+      "text/html": [
+       "<p><span style=\"font-family: monospace;\">StaticSamples</span> with data:</p><div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th>0</th>\n",
+       "      <th>1</th>\n",
+       "      <th>2</th>\n",
+       "      <th>3</th>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_idx</th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th>0</th>\n",
+       "      <td>0.374540</td>\n",
+       "      <td>0.950714</td>\n",
+       "      <td>0.731994</td>\n",
+       "      <td>0.598658</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>1</th>\n",
+       "      <td>0.156019</td>\n",
+       "      <td>0.155995</td>\n",
+       "      <td>0.058084</td>\n",
+       "      <td>0.866176</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>2</th>\n",
+       "      <td>0.601115</td>\n",
+       "      <td>0.708073</td>\n",
+       "      <td>0.020584</td>\n",
+       "      <td>0.969910</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>3</th>\n",
+       "      <td>0.832443</td>\n",
+       "      <td>0.212339</td>\n",
+       "      <td>0.181825</td>\n",
+       "      <td>0.183405</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>0.304242</td>\n",
+       "      <td>0.524756</td>\n",
+       "      <td>0.431945</td>\n",
+       "      <td>0.291229</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>...</th>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>95</th>\n",
+       "      <td>0.118165</td>\n",
+       "      <td>0.696737</td>\n",
+       "      <td>0.628943</td>\n",
+       "      <td>0.877472</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>96</th>\n",
+       "      <td>0.735071</td>\n",
+       "      <td>0.803481</td>\n",
+       "      <td>0.282035</td>\n",
+       "      <td>0.177440</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>97</th>\n",
+       "      <td>0.750615</td>\n",
+       "      <td>0.806835</td>\n",
+       "      <td>0.990505</td>\n",
+       "      <td>0.412618</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>98</th>\n",
+       "      <td>0.372018</td>\n",
+       "      <td>0.776413</td>\n",
+       "      <td>0.340804</td>\n",
+       "      <td>0.930757</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>99</th>\n",
+       "      <td>0.858413</td>\n",
+       "      <td>0.428994</td>\n",
+       "      <td>0.750871</td>\n",
+       "      <td>0.754543</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "<p>100 rows × 4 columns</p>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "StaticSamples with data:\n",
+       "                   0         1         2         3\n",
+       "sample_idx                                        \n",
+       "0           0.374540  0.950714  0.731994  0.598658\n",
+       "1           0.156019  0.155995  0.058084  0.866176\n",
+       "2           0.601115  0.708073  0.020584  0.969910\n",
+       "3           0.832443  0.212339  0.181825  0.183405\n",
+       "4           0.304242  0.524756  0.431945  0.291229\n",
+       "...              ...       ...       ...       ...\n",
+       "95          0.118165  0.696737  0.628943  0.877472\n",
+       "96          0.735071  0.803481  0.282035  0.177440\n",
+       "97          0.750615  0.806835  0.990505  0.412618\n",
+       "98          0.372018  0.776413  0.340804  0.930757\n",
+       "99          0.858413  0.428994  0.750871  0.754543\n",
+       "\n",
+       "[100 rows x 4 columns]"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "predictive.targets:\n"
+     ]
+    },
+    {
+     "data": {
+      "text/html": [
+       "<p><span style=\"font-family: monospace;\">StaticSamples</span> with data:</p><div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th>0</th>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_idx</th>\n",
+       "      <th></th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th>0</th>\n",
+       "      <td>0</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>1</th>\n",
+       "      <td>1</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>2</th>\n",
+       "      <td>0</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>3</th>\n",
+       "      <td>0</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>1</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>...</th>\n",
+       "      <td>...</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>95</th>\n",
+       "      <td>1</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>96</th>\n",
+       "      <td>1</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>97</th>\n",
+       "      <td>1</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>98</th>\n",
+       "      <td>0</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>99</th>\n",
+       "      <td>0</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "<p>100 rows × 1 columns</p>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "StaticSamples with data:\n",
+       "            0\n",
+       "sample_idx   \n",
+       "0           0\n",
+       "1           1\n",
+       "2           0\n",
+       "3           0\n",
+       "4           1\n",
+       "...        ..\n",
+       "95          1\n",
+       "96          1\n",
+       "97          1\n",
+       "98          0\n",
+       "99          0\n",
+       "\n",
+       "[100 rows x 1 columns]"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "# Display information about each dataloader's default loaded dataset.\n",
+    "\n",
+    "from tempor.utils.dataloaders import all_dataloaders\n",
+    "\n",
+    "from IPython.display import display\n",
+    "\n",
+    "for dataloader_cls in all_dataloaders:\n",
+    "    print(f\"\\n{'-' * 80}\\n\")\n",
+    "\n",
+    "    print(f\"{dataloader_cls.__name__} loads the following dataset:\\n\")\n",
+    "    data = dataloader_cls().load()\n",
+    "    print(data)\n",
+    "\n",
+    "    print(\"This contains:\", end=\"\\n\\n\")\n",
+    "\n",
+    "    print(\"time_series:\")\n",
+    "    display(data.time_series)\n",
+    "    if data.static is not None:\n",
+    "        print(\"static:\")\n",
+    "        display(data.static)\n",
+    "    if data.predictive.targets is not None:\n",
+    "        print(\"predictive.targets:\")\n",
+    "        display(data.predictive.targets)\n",
+    "    if data.predictive.treatments is not None:\n",
+    "        print(\"predictive.treatments:\")\n",
+    "        display(data.predictive.treatments)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## 🎉 Congratulations!\n",
+    "\n",
+    "Congratulations on completing this notebook tutorial! If you enjoyed this and would like to join the movement towards *Machine learning and AI for Medicine*, you can do so in the following ways!\n",
+    "\n",
+    "\n",
+    "\n",
+    "### ⭐ Star [TemporAI](https://github.com/vanderschaarlab/temporai) on GitHub\n",
+    "\n",
+    "- The easiest way to help our community is by just starring the repos! This helps raise awareness of the tools we're building.\n",
+    "\n",
+    "\n",
+    "\n",
+    "### Check out other projects from [vanderschaarlab](https://github.com/vanderschaarlab)\n",
+    "- 📝 [HyperImpute](https://github.com/vanderschaarlab/hyperimpute)\n",
+    "- 📊 [AutoPrognosis](https://github.com/vanderschaarlab/autoprognosis)\n",
+    "- 🤖 [SynthCity](https://github.com/vanderschaarlab/synthcity)\n",
+    " "
+   ]
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "RE_py38_temporai",
+   "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.15"
+  },
+  "orig_nbformat": 4
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/tutorials/extending/tutorial01_custom_plugin.ipynb b/tutorials/extending/tutorial01_custom_plugin.ipynb
new file mode 100644
index 00000000..c78b619e
--- /dev/null
+++ b/tutorials/extending/tutorial01_custom_plugin.ipynb
@@ -0,0 +1,749 @@
+{
+ "cells": [
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Extending TemporAI Tutorial 01: Writing a Custom Plugin\n",
+    "\n",
+    "This tutorial shows how to extend TemporAI by wring a custom plugin."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "*Skip the below cell if you are not on Google Colab / already have TemporAI installed:*"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "%pip install temporai\n",
+    "\n",
+    "# Or from the repo, for the latest version:\n",
+    "# %pip install git+https://github.com/vanderschaarlab/temporai.git"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Writing a Custom `Plugin` 101\n",
+    "\n",
+    "In order to write a custom plugin for TemporAI, you need to do the following:\n",
+    "1. Inherit from the appropriate **base class** for the type of plugin you are writing.\n",
+    "2. Implement the **methods** the plugin needs.\n",
+    "3. **Register** the plugin with TemporAI.\n",
+    "\n",
+    "We will go through an example in this tutorial."
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### 1. Inherit from the appropriate **base class** for the type of plugin you are writing.\n",
+    "\n",
+    "You need to find which type (category) of plugin you are writing.\n",
+    "\n",
+    "A summary of different plugin categories is available in the \n",
+    "[README](https://github.com/vanderschaarlab/temporai/blob/main/README.md#-methods).\n",
+    "\n",
+    "You can also view all the different plugin categories as so:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['prediction.one_off.classification',\n",
+       " 'prediction.one_off.regression',\n",
+       " 'prediction.temporal.classification',\n",
+       " 'prediction.temporal.regression',\n",
+       " 'preprocessing.imputation.static',\n",
+       " 'preprocessing.imputation.temporal',\n",
+       " 'preprocessing.nop',\n",
+       " 'preprocessing.scaling.static',\n",
+       " 'preprocessing.scaling.temporal',\n",
+       " 'time_to_event',\n",
+       " 'treatments.one_off.regression',\n",
+       " 'treatments.temporal.classification',\n",
+       " 'treatments.temporal.regression']"
+      ]
+     },
+     "execution_count": 2,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "from tempor.plugins import plugin_loader\n",
+    "\n",
+    "plugin_categories = plugin_loader.list_categories()\n",
+    "\n",
+    "list(plugin_categories.keys())"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Remember you can also see the existing plugins and how they correspond to different categories, as follows:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\">{</span>\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   </span><span style=\"color: #008000; text-decoration-color: #008000\">'prediction'</span>: <span style=\"font-weight: bold\">{</span>\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   │   </span><span style=\"color: #008000; text-decoration-color: #008000\">'one_off'</span>: <span style=\"font-weight: bold\">{</span>\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   │   │   </span><span style=\"color: #008000; text-decoration-color: #008000\">'classification'</span>: <span style=\"font-weight: bold\">[</span><span style=\"color: #008000; text-decoration-color: #008000\">'cde_classifier'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'ode_classifier'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'nn_classifier'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'laplace_ode_classifier'</span><span style=\"font-weight: bold\">]</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   │   │   </span><span style=\"color: #008000; text-decoration-color: #008000\">'regression'</span>: <span style=\"font-weight: bold\">[</span><span style=\"color: #008000; text-decoration-color: #008000\">'laplace_ode_regressor'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'nn_regressor'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'ode_regressor'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'cde_regressor'</span><span style=\"font-weight: bold\">]</span>\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   │   </span><span style=\"font-weight: bold\">}</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   │   </span><span style=\"color: #008000; text-decoration-color: #008000\">'temporal'</span>: <span style=\"font-weight: bold\">{</span><span style=\"color: #008000; text-decoration-color: #008000\">'classification'</span>: <span style=\"font-weight: bold\">[</span><span style=\"color: #008000; text-decoration-color: #008000\">'seq2seq_classifier'</span><span style=\"font-weight: bold\">]</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'regression'</span>: <span style=\"font-weight: bold\">[</span><span style=\"color: #008000; text-decoration-color: #008000\">'seq2seq_regressor'</span><span style=\"font-weight: bold\">]}</span>\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   </span><span style=\"font-weight: bold\">}</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   </span><span style=\"color: #008000; text-decoration-color: #008000\">'preprocessing'</span>: <span style=\"font-weight: bold\">{</span>\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   │   </span><span style=\"color: #008000; text-decoration-color: #008000\">'imputation'</span>: <span style=\"font-weight: bold\">{</span><span style=\"color: #008000; text-decoration-color: #008000\">'static'</span>: <span style=\"font-weight: bold\">[</span><span style=\"color: #008000; text-decoration-color: #008000\">'static_imputation'</span><span style=\"font-weight: bold\">]</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'temporal'</span>: <span style=\"font-weight: bold\">[</span><span style=\"color: #008000; text-decoration-color: #008000\">'ffill'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'bfill'</span><span style=\"font-weight: bold\">]}</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   │   </span><span style=\"color: #008000; text-decoration-color: #008000\">'nop'</span>: <span style=\"font-weight: bold\">[</span><span style=\"color: #008000; text-decoration-color: #008000\">'nop_transformer'</span><span style=\"font-weight: bold\">]</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   │   </span><span style=\"color: #008000; text-decoration-color: #008000\">'scaling'</span>: <span style=\"font-weight: bold\">{</span>\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   │   │   </span><span style=\"color: #008000; text-decoration-color: #008000\">'static'</span>: <span style=\"font-weight: bold\">[</span><span style=\"color: #008000; text-decoration-color: #008000\">'static_minmax_scaler'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'static_standard_scaler'</span><span style=\"font-weight: bold\">]</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   │   │   </span><span style=\"color: #008000; text-decoration-color: #008000\">'temporal'</span>: <span style=\"font-weight: bold\">[</span><span style=\"color: #008000; text-decoration-color: #008000\">'ts_minmax_scaler'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'ts_standard_scaler'</span><span style=\"font-weight: bold\">]</span>\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   │   </span><span style=\"font-weight: bold\">}</span>\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   </span><span style=\"font-weight: bold\">}</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   </span><span style=\"color: #008000; text-decoration-color: #008000\">'time_to_event'</span>: <span style=\"font-weight: bold\">[</span><span style=\"color: #008000; text-decoration-color: #008000\">'ts_coxph'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'ts_xgb'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'dynamic_deephit'</span><span style=\"font-weight: bold\">]</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   </span><span style=\"color: #008000; text-decoration-color: #008000\">'treatments'</span>: <span style=\"font-weight: bold\">{</span>\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   │   </span><span style=\"color: #008000; text-decoration-color: #008000\">'one_off'</span>: <span style=\"font-weight: bold\">{</span><span style=\"color: #008000; text-decoration-color: #008000\">'regression'</span>: <span style=\"font-weight: bold\">[</span><span style=\"color: #008000; text-decoration-color: #008000\">'synctwin_regressor'</span><span style=\"font-weight: bold\">]}</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   │   </span><span style=\"color: #008000; text-decoration-color: #008000\">'temporal'</span>: <span style=\"font-weight: bold\">{</span><span style=\"color: #008000; text-decoration-color: #008000\">'classification'</span>: <span style=\"font-weight: bold\">[</span><span style=\"color: #008000; text-decoration-color: #008000\">'crn_classifier'</span><span style=\"font-weight: bold\">]</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'regression'</span>: <span style=\"font-weight: bold\">[</span><span style=\"color: #008000; text-decoration-color: #008000\">'crn_regressor'</span><span style=\"font-weight: bold\">]}</span>\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   </span><span style=\"font-weight: bold\">}</span>\n",
+       "<span style=\"font-weight: bold\">}</span>\n",
+       "</pre>\n"
+      ],
+      "text/plain": [
+       "\u001b[1m{\u001b[0m\n",
+       "\u001b[2;32m│   \u001b[0m\u001b[32m'prediction'\u001b[0m: \u001b[1m{\u001b[0m\n",
+       "\u001b[2;32m│   │   \u001b[0m\u001b[32m'one_off'\u001b[0m: \u001b[1m{\u001b[0m\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[32m'classification'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'cde_classifier'\u001b[0m, \u001b[32m'ode_classifier'\u001b[0m, \u001b[32m'nn_classifier'\u001b[0m, \u001b[32m'laplace_ode_classifier'\u001b[0m\u001b[1m]\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[32m'regression'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'laplace_ode_regressor'\u001b[0m, \u001b[32m'nn_regressor'\u001b[0m, \u001b[32m'ode_regressor'\u001b[0m, \u001b[32m'cde_regressor'\u001b[0m\u001b[1m]\u001b[0m\n",
+       "\u001b[2;32m│   │   \u001b[0m\u001b[1m}\u001b[0m,\n",
+       "\u001b[2;32m│   │   \u001b[0m\u001b[32m'temporal'\u001b[0m: \u001b[1m{\u001b[0m\u001b[32m'classification'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'seq2seq_classifier'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'regression'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'seq2seq_regressor'\u001b[0m\u001b[1m]\u001b[0m\u001b[1m}\u001b[0m\n",
+       "\u001b[2;32m│   \u001b[0m\u001b[1m}\u001b[0m,\n",
+       "\u001b[2;32m│   \u001b[0m\u001b[32m'preprocessing'\u001b[0m: \u001b[1m{\u001b[0m\n",
+       "\u001b[2;32m│   │   \u001b[0m\u001b[32m'imputation'\u001b[0m: \u001b[1m{\u001b[0m\u001b[32m'static'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'static_imputation'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'temporal'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'ffill'\u001b[0m, \u001b[32m'bfill'\u001b[0m\u001b[1m]\u001b[0m\u001b[1m}\u001b[0m,\n",
+       "\u001b[2;32m│   │   \u001b[0m\u001b[32m'nop'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'nop_transformer'\u001b[0m\u001b[1m]\u001b[0m,\n",
+       "\u001b[2;32m│   │   \u001b[0m\u001b[32m'scaling'\u001b[0m: \u001b[1m{\u001b[0m\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[32m'static'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'static_minmax_scaler'\u001b[0m, \u001b[32m'static_standard_scaler'\u001b[0m\u001b[1m]\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[32m'temporal'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'ts_minmax_scaler'\u001b[0m, \u001b[32m'ts_standard_scaler'\u001b[0m\u001b[1m]\u001b[0m\n",
+       "\u001b[2;32m│   │   \u001b[0m\u001b[1m}\u001b[0m\n",
+       "\u001b[2;32m│   \u001b[0m\u001b[1m}\u001b[0m,\n",
+       "\u001b[2;32m│   \u001b[0m\u001b[32m'time_to_event'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'ts_coxph'\u001b[0m, \u001b[32m'ts_xgb'\u001b[0m, \u001b[32m'dynamic_deephit'\u001b[0m\u001b[1m]\u001b[0m,\n",
+       "\u001b[2;32m│   \u001b[0m\u001b[32m'treatments'\u001b[0m: \u001b[1m{\u001b[0m\n",
+       "\u001b[2;32m│   │   \u001b[0m\u001b[32m'one_off'\u001b[0m: \u001b[1m{\u001b[0m\u001b[32m'regression'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'synctwin_regressor'\u001b[0m\u001b[1m]\u001b[0m\u001b[1m}\u001b[0m,\n",
+       "\u001b[2;32m│   │   \u001b[0m\u001b[32m'temporal'\u001b[0m: \u001b[1m{\u001b[0m\u001b[32m'classification'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'crn_classifier'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'regression'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'crn_regressor'\u001b[0m\u001b[1m]\u001b[0m\u001b[1m}\u001b[0m\n",
+       "\u001b[2;32m│   \u001b[0m\u001b[1m}\u001b[0m\n",
+       "\u001b[1m}\u001b[0m\n"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "all_plugins = plugin_loader.list()\n",
+    "\n",
+    "from rich.pretty import pprint  # For prettifying the print output only.\n",
+    "\n",
+    "pprint(all_plugins, indent_guides=True)"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Let's say you would like to write a plugin of category `\"prediction.one_off.classification\"`.\n",
+    "\n",
+    "You can find which base class you need to inherit from as follows."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Base classes for all categories:\n"
+     ]
+    },
+    {
+     "data": {
+      "text/html": [
+       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\">{</span>\n",
+       "    <span style=\"color: #008000; text-decoration-color: #008000\">'prediction.one_off.classification'</span>: <span style=\"font-weight: bold\">&lt;</span><span style=\"color: #ff00ff; text-decoration-color: #ff00ff; font-weight: bold\">class</span><span style=\"color: #000000; text-decoration-color: #000000\"> </span><span style=\"color: #008000; text-decoration-color: #008000\">'tempor.plugins.prediction.one_off.classification.BaseOneOffClassifier'</span><span style=\"color: #000000; text-decoration-color: #000000\">&gt;,</span>\n",
+       "<span style=\"color: #000000; text-decoration-color: #000000\">    </span><span style=\"color: #008000; text-decoration-color: #008000\">'prediction.one_off.regression'</span><span style=\"color: #000000; text-decoration-color: #000000\">: &lt;class </span><span style=\"color: #008000; text-decoration-color: #008000\">'tempor.plugins.prediction.one_off.regression.BaseOneOffRegressor'</span><span style=\"color: #000000; text-decoration-color: #000000\">&gt;,</span>\n",
+       "<span style=\"color: #000000; text-decoration-color: #000000\">    </span><span style=\"color: #008000; text-decoration-color: #008000\">'prediction.temporal.classification'</span><span style=\"color: #000000; text-decoration-color: #000000\">: &lt;class </span><span style=\"color: #008000; text-decoration-color: #008000\">'tempor.plugins.prediction.temporal.classification.BaseTemporalClassifier'</span><span style=\"color: #000000; text-decoration-color: #000000\">&gt;,</span>\n",
+       "<span style=\"color: #000000; text-decoration-color: #000000\">    </span><span style=\"color: #008000; text-decoration-color: #008000\">'prediction.temporal.regression'</span><span style=\"color: #000000; text-decoration-color: #000000\">: &lt;class </span><span style=\"color: #008000; text-decoration-color: #008000\">'tempor.plugins.prediction.temporal.regression.BaseTemporalRegressor'</span><span style=\"color: #000000; text-decoration-color: #000000\">&gt;,</span>\n",
+       "<span style=\"color: #000000; text-decoration-color: #000000\">    </span><span style=\"color: #008000; text-decoration-color: #008000\">'preprocessing.imputation.static'</span><span style=\"color: #000000; text-decoration-color: #000000\">: &lt;class </span><span style=\"color: #008000; text-decoration-color: #008000\">'tempor.plugins.preprocessing.imputation._base.BaseImputer'</span><span style=\"color: #000000; text-decoration-color: #000000\">&gt;,</span>\n",
+       "<span style=\"color: #000000; text-decoration-color: #000000\">    </span><span style=\"color: #008000; text-decoration-color: #008000\">'preprocessing.imputation.temporal'</span><span style=\"color: #000000; text-decoration-color: #000000\">: &lt;class </span><span style=\"color: #008000; text-decoration-color: #008000\">'tempor.plugins.preprocessing.imputation._base.BaseImputer'</span><span style=\"color: #000000; text-decoration-color: #000000\">&gt;,</span>\n",
+       "<span style=\"color: #000000; text-decoration-color: #000000\">    </span><span style=\"color: #008000; text-decoration-color: #008000\">'preprocessing.nop'</span><span style=\"color: #000000; text-decoration-color: #000000\">: &lt;class </span><span style=\"color: #008000; text-decoration-color: #008000\">'tempor.plugins.core._base_transformer.BaseTransformer'</span><span style=\"color: #000000; text-decoration-color: #000000\">&gt;,</span>\n",
+       "<span style=\"color: #000000; text-decoration-color: #000000\">    </span><span style=\"color: #008000; text-decoration-color: #008000\">'preprocessing.scaling.static'</span><span style=\"color: #000000; text-decoration-color: #000000\">: &lt;class </span><span style=\"color: #008000; text-decoration-color: #008000\">'tempor.plugins.preprocessing.scaling._base.BaseScaler'</span><span style=\"color: #000000; text-decoration-color: #000000\">&gt;,</span>\n",
+       "<span style=\"color: #000000; text-decoration-color: #000000\">    </span><span style=\"color: #008000; text-decoration-color: #008000\">'preprocessing.scaling.temporal'</span><span style=\"color: #000000; text-decoration-color: #000000\">: &lt;class </span><span style=\"color: #008000; text-decoration-color: #008000\">'tempor.plugins.preprocessing.scaling._base.BaseScaler'</span><span style=\"color: #000000; text-decoration-color: #000000\">&gt;,</span>\n",
+       "<span style=\"color: #000000; text-decoration-color: #000000\">    </span><span style=\"color: #008000; text-decoration-color: #008000\">'time_to_event'</span><span style=\"color: #000000; text-decoration-color: #000000\">: &lt;class </span><span style=\"color: #008000; text-decoration-color: #008000\">'tempor.plugins.time_to_event.BaseTimeToEventAnalysis'</span><span style=\"color: #000000; text-decoration-color: #000000\">&gt;,</span>\n",
+       "<span style=\"color: #000000; text-decoration-color: #000000\">    </span><span style=\"color: #008000; text-decoration-color: #008000\">'treatments.one_off.regression'</span><span style=\"color: #000000; text-decoration-color: #000000\">: &lt;class </span><span style=\"color: #008000; text-decoration-color: #008000\">'tempor.plugins.treatments.one_off._base.BaseOneOffTreatmentEffects'</span><span style=\"color: #000000; text-decoration-color: #000000\">&gt;,</span>\n",
+       "<span style=\"color: #000000; text-decoration-color: #000000\">    </span><span style=\"color: #008000; text-decoration-color: #008000\">'treatments.temporal.classification'</span><span style=\"color: #000000; text-decoration-color: #000000\">: &lt;class </span><span style=\"color: #008000; text-decoration-color: #008000\">'tempor.plugins.treatments.temporal._base.BaseTemporalTreatmentEffects'</span><span style=\"color: #000000; text-decoration-color: #000000\">&gt;,</span>\n",
+       "<span style=\"color: #000000; text-decoration-color: #000000\">    </span><span style=\"color: #008000; text-decoration-color: #008000\">'treatments.temporal.regression'</span><span style=\"color: #000000; text-decoration-color: #000000\">: &lt;class </span><span style=\"color: #008000; text-decoration-color: #008000\">'tempor.plugins.treatments.temporal._base.BaseTemporalTreatmentEffects'</span><span style=\"font-weight: bold\">&gt;</span>\n",
+       "<span style=\"font-weight: bold\">}</span>\n",
+       "</pre>\n"
+      ],
+      "text/plain": [
+       "\u001b[1m{\u001b[0m\n",
+       "    \u001b[32m'prediction.one_off.classification'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'tempor.plugins.prediction.one_off.classification.BaseOneOffClassifier'\u001b[0m\u001b[39m>,\u001b[0m\n",
+       "\u001b[39m    \u001b[0m\u001b[32m'prediction.one_off.regression'\u001b[0m\u001b[39m: <class \u001b[0m\u001b[32m'tempor.plugins.prediction.one_off.regression.BaseOneOffRegressor'\u001b[0m\u001b[39m>,\u001b[0m\n",
+       "\u001b[39m    \u001b[0m\u001b[32m'prediction.temporal.classification'\u001b[0m\u001b[39m: <class \u001b[0m\u001b[32m'tempor.plugins.prediction.temporal.classification.BaseTemporalClassifier'\u001b[0m\u001b[39m>,\u001b[0m\n",
+       "\u001b[39m    \u001b[0m\u001b[32m'prediction.temporal.regression'\u001b[0m\u001b[39m: <class \u001b[0m\u001b[32m'tempor.plugins.prediction.temporal.regression.BaseTemporalRegressor'\u001b[0m\u001b[39m>,\u001b[0m\n",
+       "\u001b[39m    \u001b[0m\u001b[32m'preprocessing.imputation.static'\u001b[0m\u001b[39m: <class \u001b[0m\u001b[32m'tempor.plugins.preprocessing.imputation._base.BaseImputer'\u001b[0m\u001b[39m>,\u001b[0m\n",
+       "\u001b[39m    \u001b[0m\u001b[32m'preprocessing.imputation.temporal'\u001b[0m\u001b[39m: <class \u001b[0m\u001b[32m'tempor.plugins.preprocessing.imputation._base.BaseImputer'\u001b[0m\u001b[39m>,\u001b[0m\n",
+       "\u001b[39m    \u001b[0m\u001b[32m'preprocessing.nop'\u001b[0m\u001b[39m: <class \u001b[0m\u001b[32m'tempor.plugins.core._base_transformer.BaseTransformer'\u001b[0m\u001b[39m>,\u001b[0m\n",
+       "\u001b[39m    \u001b[0m\u001b[32m'preprocessing.scaling.static'\u001b[0m\u001b[39m: <class \u001b[0m\u001b[32m'tempor.plugins.preprocessing.scaling._base.BaseScaler'\u001b[0m\u001b[39m>,\u001b[0m\n",
+       "\u001b[39m    \u001b[0m\u001b[32m'preprocessing.scaling.temporal'\u001b[0m\u001b[39m: <class \u001b[0m\u001b[32m'tempor.plugins.preprocessing.scaling._base.BaseScaler'\u001b[0m\u001b[39m>,\u001b[0m\n",
+       "\u001b[39m    \u001b[0m\u001b[32m'time_to_event'\u001b[0m\u001b[39m: <class \u001b[0m\u001b[32m'tempor.plugins.time_to_event.BaseTimeToEventAnalysis'\u001b[0m\u001b[39m>,\u001b[0m\n",
+       "\u001b[39m    \u001b[0m\u001b[32m'treatments.one_off.regression'\u001b[0m\u001b[39m: <class \u001b[0m\u001b[32m'tempor.plugins.treatments.one_off._base.BaseOneOffTreatmentEffects'\u001b[0m\u001b[39m>,\u001b[0m\n",
+       "\u001b[39m    \u001b[0m\u001b[32m'treatments.temporal.classification'\u001b[0m\u001b[39m: <class \u001b[0m\u001b[32m'tempor.plugins.treatments.temporal._base.BaseTemporalTreatmentEffects'\u001b[0m\u001b[39m>,\u001b[0m\n",
+       "\u001b[39m    \u001b[0m\u001b[32m'treatments.temporal.regression'\u001b[0m\u001b[39m: <class \u001b[0m\u001b[32m'tempor.plugins.treatments.temporal._base.BaseTemporalTreatmentEffects'\u001b[0m\u001b[1m>\u001b[0m\n",
+       "\u001b[1m}\u001b[0m\n"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Base class you need:\n",
+      "<class 'tempor.plugins.prediction.one_off.classification.BaseOneOffClassifier'>\n"
+     ]
+    }
+   ],
+   "source": [
+    "plugin_categories = plugin_loader.list_categories()\n",
+    "\n",
+    "print(\"Base classes for all categories:\")\n",
+    "pprint(plugin_categories, indent_guides=False)\n",
+    "\n",
+    "print(\"Base class you need:\")\n",
+    "print(plugin_categories[\"prediction.one_off.classification\"])"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "You can then find the class in the TemporAI source code, to see its method signatures etc."
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### 2. Implement the **methods** the plugin needs.\n",
+    "\n",
+    "Different category plugins have different methods that need to be implemented, but the key methods are:\n",
+    "* `_fit()` where you provide your implementation of the fitting (training).\n",
+    "* `_predict()` where you provide your implementation of the prediction (inference).\n",
+    "* `_transform()` where you provide your implementation of data transformation (for preprocessing plugins).\n",
+    "\n",
+    "Classification-related plugins also have `_predict_proba()` and treatment effects plugins have `_predict_counterfactuals()`.\n",
+    "\n",
+    "Note that these methods have a preceding underscore `_`, and are different from the corresponding \"public\" methods\n",
+    "without the underscore (e.g `fit()`). When extending, you need to implement the `_<...>` method,\n",
+    "and the corresponding \"public\" method in TemporAI is what the user of your plugin will call.\n",
+    "The \"public\" methods also do various necessary validation and other checks behind the scenes.\n",
+    "\n",
+    "If you haven't implemented some required method for the plugin, Python will notify you by raising an exception when you\n",
+    "attempt to instantiate your plugin (see [Python `abc`](https://docs.python.org/3/library/abc.html)).\n"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "In our example case, you will need to implement the following methods for `BaseOneOffClassifier`:\n",
+    "\n",
+    "```python\n",
+    "from tempor.plugins.prediction.one_off.classification import BaseOneOffClassifier\n",
+    "\n",
+    "class MyPlugin(BaseOneOffClassifier):\n",
+    "    # The initializer:\n",
+    "    def __init__(self, **params) -> None:\n",
+    "        ...\n",
+    "\n",
+    "    # The _fit implementation.\n",
+    "    def _fit(self, data: dataset.BaseDataset, *args, **kwargs):\n",
+    "        ...\n",
+    "\n",
+    "    def _predict(self, data: dataset.PredictiveDataset, *args, **kwargs) -> samples.StaticSamples:\n",
+    "        ...\n",
+    "\n",
+    "    def _predict_proba(self, data: dataset.PredictiveDataset, *args, **kwargs) -> samples.StaticSamples:\n",
+    "        ...\n",
+    "    \n",
+    "    @staticmethod\n",
+    "    def hyperparameter_space(*args, **kwargs):\n",
+    "        # This method is not currently used in TemporAI (it will be used once AutoML component is implemented).\n",
+    "        # For now, you may just return an empty list.\n",
+    "        ...\n",
+    "``` "
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### 3. **Register** the plugin with TemporAI.\n",
+    "\n",
+    "Registering your plugin with TemporAI is very simple, you need to use the `register_plugin` decorator,\n",
+    "as shown in the example below.\n",
+    "\n",
+    "You will need to specify the `name` of your plugin and its `category` in the decorator.\n",
+    "\n",
+    "```python\n",
+    "from tempor.plugins.core import register_plugin\n",
+    "\n",
+    "@register_plugin(name=\"my_plugin\", category=\"prediction.one_off.classification\")\n",
+    "class MyPlugin(BaseOneOffClassifier):\n",
+    "    ...\n",
+    "```"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Note on `__init__` parameters (arguments)\n",
+    "\n",
+    "You will also need to define the input parameters (arguments) that will be passed into your plugin's `__init__` in the\n",
+    "following way:\n",
+    "\n",
+    "```python\n",
+    "import dataclasses\n",
+    "\n",
+    "# 1. Write dataclass with your __init__ parameters:\n",
+    "@dataclasses.dataclass\n",
+    "class MyPluginParams:\n",
+    "    # Specify the parameter, data type and default value as below:\n",
+    "    lr: float = 0.001\n",
+    "    batch_size: int = 100\n",
+    "\n",
+    "class MyPlugin(BaseOneOffClassifier):\n",
+    "    # 2. Set the `ParamsDefinition` class variable in your plugin to this dataclass.\n",
+    "    ParamsDefinition = MyPluginParams\n",
+    "    \n",
+    "    def __init__(self, **params) -> None:\n",
+    "        # 3. Call the parent __init__ as so.\n",
+    "        super().__init__(**params)\n",
+    "\n",
+    "        # 4. You will now be able to access these in your class like so:\n",
+    "        print(self.params.lr)\n",
+    "        print(self.params.batch_size) \n",
+    "\n",
+    "\n",
+    "# 5. The user will then be able to specify the arguments as necessary when initializing your plugin:\n",
+    "model = MyPlugin(batch_size=22)\n",
+    "```\n"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Putting it all together\n",
+    "\n",
+    "Now putting this together in an example of a one-off classifier plugin that always returns `1`s."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import dataclasses\n",
+    "\n",
+    "import numpy as np\n",
+    "\n",
+    "from tempor.plugins.core import register_plugin\n",
+    "from tempor.data import dataset, samples\n",
+    "from tempor.plugins.prediction.one_off.classification import BaseOneOffClassifier\n",
+    "\n",
+    "\n",
+    "@dataclasses.dataclass\n",
+    "class MyClassifierParams:\n",
+    "    some_parameter: int = 1\n",
+    "    other_parameter: float = 0.5\n",
+    "\n",
+    "\n",
+    "@register_plugin(name=\"my_classifier\", category=\"prediction.one_off.classification\")\n",
+    "class MyClassifierClassifier(BaseOneOffClassifier):\n",
+    "    ParamsDefinition = MyClassifierParams\n",
+    "\n",
+    "    def __init__(self, **param) -> None:\n",
+    "        super().__init__(**param)\n",
+    "\n",
+    "    def _fit(self, data: dataset.BaseDataset, *args, **kwargs):\n",
+    "        \"\"\"Does nothing.\"\"\"\n",
+    "        return self  # Fit method needs to return `self`.\n",
+    "\n",
+    "    def _predict(self, data: dataset.PredictiveDataset, *args, **kwargs) -> samples.StaticSamples:\n",
+    "        \"\"\"Always returns 1\"\"\"\n",
+    "\n",
+    "        assert data.predictive.targets is not None\n",
+    "        preds = np.ones_like(data.predictive.targets.numpy())\n",
+    "\n",
+    "        return samples.StaticSamples.from_numpy(preds, dtype=int)\n",
+    "\n",
+    "    def _predict_proba(self, data: dataset.PredictiveDataset, *args, **kwargs) -> samples.StaticSamples:\n",
+    "        \"\"\"Always returns 1.0\"\"\"\n",
+    "\n",
+    "        assert data.predictive.targets is not None\n",
+    "        preds = np.ones_like(data.predictive.targets.numpy())\n",
+    "\n",
+    "        return samples.StaticSamples.from_numpy(preds, dtype=float)\n",
+    "\n",
+    "    @staticmethod\n",
+    "    def hyperparameter_space(*args, **kwargs):\n",
+    "        return []"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "We now see our plugin in TemporAI:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\">{</span>\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   </span><span style=\"color: #008000; text-decoration-color: #008000\">'prediction'</span>: <span style=\"font-weight: bold\">{</span>\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   │   </span><span style=\"color: #008000; text-decoration-color: #008000\">'one_off'</span>: <span style=\"font-weight: bold\">{</span>\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   │   │   </span><span style=\"color: #008000; text-decoration-color: #008000\">'classification'</span>: <span style=\"font-weight: bold\">[</span>\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   │   │   │   </span><span style=\"color: #008000; text-decoration-color: #008000\">'cde_classifier'</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   │   │   │   </span><span style=\"color: #008000; text-decoration-color: #008000\">'ode_classifier'</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   │   │   │   </span><span style=\"color: #008000; text-decoration-color: #008000\">'nn_classifier'</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   │   │   │   </span><span style=\"color: #008000; text-decoration-color: #008000\">'laplace_ode_classifier'</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   │   │   │   </span><span style=\"color: #008000; text-decoration-color: #008000\">'my_classifier'</span>\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   │   │   </span><span style=\"font-weight: bold\">]</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   │   │   </span><span style=\"color: #008000; text-decoration-color: #008000\">'regression'</span>: <span style=\"font-weight: bold\">[</span><span style=\"color: #008000; text-decoration-color: #008000\">'laplace_ode_regressor'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'nn_regressor'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'ode_regressor'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'cde_regressor'</span><span style=\"font-weight: bold\">]</span>\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   │   </span><span style=\"font-weight: bold\">}</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   │   </span><span style=\"color: #008000; text-decoration-color: #008000\">'temporal'</span>: <span style=\"font-weight: bold\">{</span><span style=\"color: #008000; text-decoration-color: #008000\">'classification'</span>: <span style=\"font-weight: bold\">[</span><span style=\"color: #008000; text-decoration-color: #008000\">'seq2seq_classifier'</span><span style=\"font-weight: bold\">]</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'regression'</span>: <span style=\"font-weight: bold\">[</span><span style=\"color: #008000; text-decoration-color: #008000\">'seq2seq_regressor'</span><span style=\"font-weight: bold\">]}</span>\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   </span><span style=\"font-weight: bold\">}</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   </span><span style=\"color: #008000; text-decoration-color: #008000\">'preprocessing'</span>: <span style=\"font-weight: bold\">{</span>\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   │   </span><span style=\"color: #008000; text-decoration-color: #008000\">'imputation'</span>: <span style=\"font-weight: bold\">{</span><span style=\"color: #008000; text-decoration-color: #008000\">'static'</span>: <span style=\"font-weight: bold\">[</span><span style=\"color: #008000; text-decoration-color: #008000\">'static_imputation'</span><span style=\"font-weight: bold\">]</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'temporal'</span>: <span style=\"font-weight: bold\">[</span><span style=\"color: #008000; text-decoration-color: #008000\">'ffill'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'bfill'</span><span style=\"font-weight: bold\">]}</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   │   </span><span style=\"color: #008000; text-decoration-color: #008000\">'nop'</span>: <span style=\"font-weight: bold\">[</span><span style=\"color: #008000; text-decoration-color: #008000\">'nop_transformer'</span><span style=\"font-weight: bold\">]</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   │   </span><span style=\"color: #008000; text-decoration-color: #008000\">'scaling'</span>: <span style=\"font-weight: bold\">{</span>\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   │   │   </span><span style=\"color: #008000; text-decoration-color: #008000\">'static'</span>: <span style=\"font-weight: bold\">[</span><span style=\"color: #008000; text-decoration-color: #008000\">'static_minmax_scaler'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'static_standard_scaler'</span><span style=\"font-weight: bold\">]</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   │   │   </span><span style=\"color: #008000; text-decoration-color: #008000\">'temporal'</span>: <span style=\"font-weight: bold\">[</span><span style=\"color: #008000; text-decoration-color: #008000\">'ts_minmax_scaler'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'ts_standard_scaler'</span><span style=\"font-weight: bold\">]</span>\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   │   </span><span style=\"font-weight: bold\">}</span>\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   </span><span style=\"font-weight: bold\">}</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   </span><span style=\"color: #008000; text-decoration-color: #008000\">'time_to_event'</span>: <span style=\"font-weight: bold\">[</span><span style=\"color: #008000; text-decoration-color: #008000\">'ts_coxph'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'ts_xgb'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'dynamic_deephit'</span><span style=\"font-weight: bold\">]</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   </span><span style=\"color: #008000; text-decoration-color: #008000\">'treatments'</span>: <span style=\"font-weight: bold\">{</span>\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   │   </span><span style=\"color: #008000; text-decoration-color: #008000\">'one_off'</span>: <span style=\"font-weight: bold\">{</span><span style=\"color: #008000; text-decoration-color: #008000\">'regression'</span>: <span style=\"font-weight: bold\">[</span><span style=\"color: #008000; text-decoration-color: #008000\">'synctwin_regressor'</span><span style=\"font-weight: bold\">]}</span>,\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   │   </span><span style=\"color: #008000; text-decoration-color: #008000\">'temporal'</span>: <span style=\"font-weight: bold\">{</span><span style=\"color: #008000; text-decoration-color: #008000\">'classification'</span>: <span style=\"font-weight: bold\">[</span><span style=\"color: #008000; text-decoration-color: #008000\">'crn_classifier'</span><span style=\"font-weight: bold\">]</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'regression'</span>: <span style=\"font-weight: bold\">[</span><span style=\"color: #008000; text-decoration-color: #008000\">'crn_regressor'</span><span style=\"font-weight: bold\">]}</span>\n",
+       "<span style=\"color: #7fbf7f; text-decoration-color: #7fbf7f\">│   </span><span style=\"font-weight: bold\">}</span>\n",
+       "<span style=\"font-weight: bold\">}</span>\n",
+       "</pre>\n"
+      ],
+      "text/plain": [
+       "\u001b[1m{\u001b[0m\n",
+       "\u001b[2;32m│   \u001b[0m\u001b[32m'prediction'\u001b[0m: \u001b[1m{\u001b[0m\n",
+       "\u001b[2;32m│   │   \u001b[0m\u001b[32m'one_off'\u001b[0m: \u001b[1m{\u001b[0m\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[32m'classification'\u001b[0m: \u001b[1m[\u001b[0m\n",
+       "\u001b[2;32m│   │   │   │   \u001b[0m\u001b[32m'cde_classifier'\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   │   \u001b[0m\u001b[32m'ode_classifier'\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   │   \u001b[0m\u001b[32m'nn_classifier'\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   │   \u001b[0m\u001b[32m'laplace_ode_classifier'\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   │   \u001b[0m\u001b[32m'my_classifier'\u001b[0m\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m]\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[32m'regression'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'laplace_ode_regressor'\u001b[0m, \u001b[32m'nn_regressor'\u001b[0m, \u001b[32m'ode_regressor'\u001b[0m, \u001b[32m'cde_regressor'\u001b[0m\u001b[1m]\u001b[0m\n",
+       "\u001b[2;32m│   │   \u001b[0m\u001b[1m}\u001b[0m,\n",
+       "\u001b[2;32m│   │   \u001b[0m\u001b[32m'temporal'\u001b[0m: \u001b[1m{\u001b[0m\u001b[32m'classification'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'seq2seq_classifier'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'regression'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'seq2seq_regressor'\u001b[0m\u001b[1m]\u001b[0m\u001b[1m}\u001b[0m\n",
+       "\u001b[2;32m│   \u001b[0m\u001b[1m}\u001b[0m,\n",
+       "\u001b[2;32m│   \u001b[0m\u001b[32m'preprocessing'\u001b[0m: \u001b[1m{\u001b[0m\n",
+       "\u001b[2;32m│   │   \u001b[0m\u001b[32m'imputation'\u001b[0m: \u001b[1m{\u001b[0m\u001b[32m'static'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'static_imputation'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'temporal'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'ffill'\u001b[0m, \u001b[32m'bfill'\u001b[0m\u001b[1m]\u001b[0m\u001b[1m}\u001b[0m,\n",
+       "\u001b[2;32m│   │   \u001b[0m\u001b[32m'nop'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'nop_transformer'\u001b[0m\u001b[1m]\u001b[0m,\n",
+       "\u001b[2;32m│   │   \u001b[0m\u001b[32m'scaling'\u001b[0m: \u001b[1m{\u001b[0m\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[32m'static'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'static_minmax_scaler'\u001b[0m, \u001b[32m'static_standard_scaler'\u001b[0m\u001b[1m]\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[32m'temporal'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'ts_minmax_scaler'\u001b[0m, \u001b[32m'ts_standard_scaler'\u001b[0m\u001b[1m]\u001b[0m\n",
+       "\u001b[2;32m│   │   \u001b[0m\u001b[1m}\u001b[0m\n",
+       "\u001b[2;32m│   \u001b[0m\u001b[1m}\u001b[0m,\n",
+       "\u001b[2;32m│   \u001b[0m\u001b[32m'time_to_event'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'ts_coxph'\u001b[0m, \u001b[32m'ts_xgb'\u001b[0m, \u001b[32m'dynamic_deephit'\u001b[0m\u001b[1m]\u001b[0m,\n",
+       "\u001b[2;32m│   \u001b[0m\u001b[32m'treatments'\u001b[0m: \u001b[1m{\u001b[0m\n",
+       "\u001b[2;32m│   │   \u001b[0m\u001b[32m'one_off'\u001b[0m: \u001b[1m{\u001b[0m\u001b[32m'regression'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'synctwin_regressor'\u001b[0m\u001b[1m]\u001b[0m\u001b[1m}\u001b[0m,\n",
+       "\u001b[2;32m│   │   \u001b[0m\u001b[32m'temporal'\u001b[0m: \u001b[1m{\u001b[0m\u001b[32m'classification'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'crn_classifier'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'regression'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'crn_regressor'\u001b[0m\u001b[1m]\u001b[0m\u001b[1m}\u001b[0m\n",
+       "\u001b[2;32m│   \u001b[0m\u001b[1m}\u001b[0m\n",
+       "\u001b[1m}\u001b[0m\n"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "`my_classifier` plugin found in the category 'prediction.one_off.classification': True\n"
+     ]
+    }
+   ],
+   "source": [
+    "from tempor.plugins import plugin_loader\n",
+    "\n",
+    "all_plugins = plugin_loader.list()\n",
+    "\n",
+    "pprint(all_plugins, indent_guides=True)\n",
+    "\n",
+    "my_classifier_found = \"my_classifier\" in all_plugins[\"prediction\"][\"one_off\"][\"classification\"]\n",
+    "print(f\"`my_classifier` plugin found in the category 'prediction.one_off.classification': {my_classifier_found}\")\n",
+    "assert my_classifier_found"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "The plugin can be used as normal."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "MyClassifierClassifier(\n",
+      "    name='my_classifier',\n",
+      "    category='prediction.one_off.classification',\n",
+      "    params={'some_parameter': 1, 'other_parameter': 0.5}\n",
+      ")\n"
+     ]
+    }
+   ],
+   "source": [
+    "# Get the plugin.\n",
+    "\n",
+    "my_classifier = plugin_loader.get(\"prediction.one_off.classification.my_classifier\")\n",
+    "\n",
+    "print(my_classifier)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Prediction:\n"
+     ]
+    },
+    {
+     "data": {
+      "text/html": [
+       "<p><span style=\"font-family: monospace;\">StaticSamples</span> with data:</p><div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th>feat_0</th>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_idx</th>\n",
+       "      <th></th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th>0</th>\n",
+       "      <td>1</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>1</th>\n",
+       "      <td>1</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>2</th>\n",
+       "      <td>1</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>3</th>\n",
+       "      <td>1</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>1</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>...</th>\n",
+       "      <td>...</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>95</th>\n",
+       "      <td>1</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>96</th>\n",
+       "      <td>1</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>97</th>\n",
+       "      <td>1</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>98</th>\n",
+       "      <td>1</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>99</th>\n",
+       "      <td>1</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "<p>100 rows × 1 columns</p>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "StaticSamples with data:\n",
+       "            feat_0\n",
+       "sample_idx        \n",
+       "0                1\n",
+       "1                1\n",
+       "2                1\n",
+       "3                1\n",
+       "4                1\n",
+       "...            ...\n",
+       "95               1\n",
+       "96               1\n",
+       "97               1\n",
+       "98               1\n",
+       "99               1\n",
+       "\n",
+       "[100 rows x 1 columns]"
+      ]
+     },
+     "execution_count": 8,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# Fit and predict on some data.\n",
+    "\n",
+    "from tempor.utils.dataloaders import SineDataLoader\n",
+    "\n",
+    "dataset = SineDataLoader(random_state=42).load()\n",
+    "\n",
+    "my_classifier.fit(dataset)\n",
+    "\n",
+    "print(\"Prediction:\")\n",
+    "my_classifier.predict(dataset)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## 🎉 Congratulations!\n",
+    "\n",
+    "Congratulations on completing this notebook tutorial! If you enjoyed this and would like to join the movement towards *Machine learning and AI for Medicine*, you can do so in the following ways!\n",
+    "\n",
+    "\n",
+    "\n",
+    "### ⭐ Star [TemporAI](https://github.com/vanderschaarlab/temporai) on GitHub\n",
+    "\n",
+    "- The easiest way to help our community is by just starring the repos! This helps raise awareness of the tools we're building.\n",
+    "\n",
+    "\n",
+    "\n",
+    "### Check out other projects from [vanderschaarlab](https://github.com/vanderschaarlab)\n",
+    "- 📝 [HyperImpute](https://github.com/vanderschaarlab/hyperimpute)\n",
+    "- 📊 [AutoPrognosis](https://github.com/vanderschaarlab/autoprognosis)\n",
+    "- 🤖 [SynthCity](https://github.com/vanderschaarlab/synthcity)\n",
+    " "
+   ]
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "RE_py38_temporai",
+   "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.15"
+  },
+  "orig_nbformat": 4
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/tutorials/tutorial01_data_format.ipynb b/tutorials/tutorial01_data_format.ipynb
deleted file mode 100644
index 8bf1aeda..00000000
--- a/tutorials/tutorial01_data_format.ipynb
+++ /dev/null
@@ -1,585 +0,0 @@
-{
- "cells": [
-  {
-   "attachments": {},
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "# Tutorial 01: Data Format\n",
-    "\n",
-    "This tutorial shows a minimal example of the data format for TemporAI."
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 1,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "import pandas as pd\n",
-    "import numpy as np"
-   ]
-  },
-  {
-   "attachments": {},
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "## Time series data\n",
-    "\n",
-    "Time series data contains data samples (e.g. patients), with features that unfold sequentially over some number of timesteps.\n",
-    "\n",
-    "Time series data should take form of a `pandas.DataFrame`, with the following specifics:\n",
-    "* The index should be a 2-level multiindex, where level `0` index represents sampled IDs, and level `1` represents the timesteps for each sample.\n",
-    "* The sample index can be comprised of either `int`s or `str`s (homogenous, not a mix of these).\n",
-    "* The time index (timesteps) may be `int`, `float` or `pandas.Timestep`-compatible format (homogenous, not a mix of these).\n",
-    "* The columns of the dataframe represent the features, column names must be `str`.\n",
-    "* Column (feature) values currently supported are: `bool`, `int`, `float`, or `pandas.Categorical` (homogenous per column).\n",
-    "\n",
-    "Other points to note:\n",
-    "* Sample IDs must be unique.\n",
-    "* (Sample ID, timestep) combination must be unique (a sample cannot have more than one of the same timestep).\n",
-    "* Null values such as `numpy.nan` are allowed and represent missing values."
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 2,
-   "metadata": {},
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "<class 'pandas.core.frame.DataFrame'>\n",
-      "MultiIndex: 7 entries, ('sample_0', 1) to ('sample_2', 9)\n",
-      "Data columns (total 3 columns):\n",
-      " #   Column    Non-Null Count  Dtype   \n",
-      "---  ------    --------------  -----   \n",
-      " 0   t_feat_0  7 non-null      int64   \n",
-      " 1   t_feat_1  6 non-null      float64 \n",
-      " 2   t_feat_2  7 non-null      category\n",
-      "dtypes: category(1), float64(1), int64(1)\n",
-      "memory usage: 725.0+ bytes\n"
-     ]
-    },
-    {
-     "data": {
-      "text/html": [
-       "<div>\n",
-       "<style scoped>\n",
-       "    .dataframe tbody tr th:only-of-type {\n",
-       "        vertical-align: middle;\n",
-       "    }\n",
-       "\n",
-       "    .dataframe tbody tr th {\n",
-       "        vertical-align: top;\n",
-       "    }\n",
-       "\n",
-       "    .dataframe thead th {\n",
-       "        text-align: right;\n",
-       "    }\n",
-       "</style>\n",
-       "<table border=\"1\" class=\"dataframe\">\n",
-       "  <thead>\n",
-       "    <tr style=\"text-align: right;\">\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th>t_feat_0</th>\n",
-       "      <th>t_feat_1</th>\n",
-       "      <th>t_feat_2</th>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>sample_idx</th>\n",
-       "      <th>time_idx</th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "    </tr>\n",
-       "  </thead>\n",
-       "  <tbody>\n",
-       "    <tr>\n",
-       "      <th rowspan=\"4\" valign=\"top\">sample_0</th>\n",
-       "      <th>1</th>\n",
-       "      <td>11</td>\n",
-       "      <td>1.1</td>\n",
-       "      <td>a</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>2</th>\n",
-       "      <td>12</td>\n",
-       "      <td>1.2</td>\n",
-       "      <td>b</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>3</th>\n",
-       "      <td>13</td>\n",
-       "      <td>1.3</td>\n",
-       "      <td>b</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>4</th>\n",
-       "      <td>14</td>\n",
-       "      <td>NaN</td>\n",
-       "      <td>c</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th rowspan=\"2\" valign=\"top\">sample_1</th>\n",
-       "      <th>2</th>\n",
-       "      <td>21</td>\n",
-       "      <td>2.1</td>\n",
-       "      <td>a</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>4</th>\n",
-       "      <td>22</td>\n",
-       "      <td>2.2</td>\n",
-       "      <td>a</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>sample_2</th>\n",
-       "      <th>9</th>\n",
-       "      <td>31</td>\n",
-       "      <td>3.1</td>\n",
-       "      <td>c</td>\n",
-       "    </tr>\n",
-       "  </tbody>\n",
-       "</table>\n",
-       "</div>"
-      ],
-      "text/plain": [
-       "                     t_feat_0  t_feat_1 t_feat_2\n",
-       "sample_idx time_idx                             \n",
-       "sample_0   1               11       1.1        a\n",
-       "           2               12       1.2        b\n",
-       "           3               13       1.3        b\n",
-       "           4               14       NaN        c\n",
-       "sample_1   2               21       2.1        a\n",
-       "           4               22       2.2        a\n",
-       "sample_2   9               31       3.1        c"
-      ]
-     },
-     "execution_count": 2,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "# Create a time series dataframe.\n",
-    "\n",
-    "time_series_df = pd.DataFrame(\n",
-    "    {\n",
-    "        \"sample_idx\": [\"sample_0\", \"sample_0\", \"sample_0\", \"sample_0\", \"sample_1\", \"sample_1\", \"sample_2\"],\n",
-    "        \"time_idx\": [1, 2, 3, 4, 2, 4, 9],\n",
-    "        \"t_feat_0\": [11, 12, 13, 14, 21, 22, 31],\n",
-    "        \"t_feat_1\": [1.1, 1.2, 1.3, np.nan, 2.1, 2.2, 3.1],\n",
-    "        \"t_feat_2\": [\"a\", \"b\", \"b\", \"c\", \"a\", \"a\", \"c\"],\n",
-    "    }\n",
-    ")\n",
-    "\n",
-    "# Set the 2-level index:\n",
-    "time_series_df.set_index(keys=[\"sample_idx\", \"time_idx\"], drop=True, inplace=True)\n",
-    "\n",
-    "# \"feat_2\" needs to be set to a categorical, as `str` format is not supported.\n",
-    "time_series_df[\"t_feat_2\"] = pd.Categorical(time_series_df[\"t_feat_2\"])\n",
-    "\n",
-    "# Preview the dataframe:\n",
-    "time_series_df.info()\n",
-    "time_series_df"
-   ]
-  },
-  {
-   "attachments": {},
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "## Static data\n",
-    "\n",
-    "Static data contains data samples (e.g. patients), features that are not associated with a particular time.\n",
-    "\n",
-    "Static data should take form of a `pandas.DataFrame`, with the following specifics:\n",
-    "* The index represents sample IDs and is a (single level) index that can be comprised of `int`s or `str`s (homogenous, not a mix of these).\n",
-    "* The columns of the dataframe represent the features, column names must be `str`.\n",
-    "* Column (feature) values currently supported are: `bool`, `int`, `float`, or `pandas.Categorical` (homogenous per column).\n",
-    "\n",
-    "Other points to note:\n",
-    "* Sample IDs must be unique.\n",
-    "* Null values such as `numpy.nan` are allowed and represent missing values."
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 3,
-   "metadata": {},
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "<class 'pandas.core.frame.DataFrame'>\n",
-      "Index: 3 entries, sample_0 to sample_2\n",
-      "Data columns (total 2 columns):\n",
-      " #   Column    Non-Null Count  Dtype  \n",
-      "---  ------    --------------  -----  \n",
-      " 0   s_feat_0  3 non-null      int64  \n",
-      " 1   s_feat_1  2 non-null      float64\n",
-      "dtypes: float64(1), int64(1)\n",
-      "memory usage: 72.0+ bytes\n"
-     ]
-    },
-    {
-     "data": {
-      "text/html": [
-       "<div>\n",
-       "<style scoped>\n",
-       "    .dataframe tbody tr th:only-of-type {\n",
-       "        vertical-align: middle;\n",
-       "    }\n",
-       "\n",
-       "    .dataframe tbody tr th {\n",
-       "        vertical-align: top;\n",
-       "    }\n",
-       "\n",
-       "    .dataframe thead th {\n",
-       "        text-align: right;\n",
-       "    }\n",
-       "</style>\n",
-       "<table border=\"1\" class=\"dataframe\">\n",
-       "  <thead>\n",
-       "    <tr style=\"text-align: right;\">\n",
-       "      <th></th>\n",
-       "      <th>s_feat_0</th>\n",
-       "      <th>s_feat_1</th>\n",
-       "    </tr>\n",
-       "  </thead>\n",
-       "  <tbody>\n",
-       "    <tr>\n",
-       "      <th>sample_0</th>\n",
-       "      <td>100</td>\n",
-       "      <td>-1.1</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>sample_1</th>\n",
-       "      <td>200</td>\n",
-       "      <td>NaN</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>sample_2</th>\n",
-       "      <td>300</td>\n",
-       "      <td>-1.3</td>\n",
-       "    </tr>\n",
-       "  </tbody>\n",
-       "</table>\n",
-       "</div>"
-      ],
-      "text/plain": [
-       "          s_feat_0  s_feat_1\n",
-       "sample_0       100      -1.1\n",
-       "sample_1       200       NaN\n",
-       "sample_2       300      -1.3"
-      ]
-     },
-     "execution_count": 3,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "# Create a static data dataframe.\n",
-    "\n",
-    "static_df = pd.DataFrame(\n",
-    "    {\n",
-    "        \"s_feat_0\": [100, 200, 300],\n",
-    "        \"s_feat_1\": [-1.1, np.nan, -1.3],\n",
-    "    },\n",
-    "    index=[\"sample_0\", \"sample_1\", \"sample_2\"],\n",
-    ")\n",
-    "\n",
-    "# Preview the dataframe:\n",
-    "static_df.info()\n",
-    "static_df"
-   ]
-  },
-  {
-   "attachments": {},
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "## Event data\n",
-    "\n",
-    "Event data contains data samples (e.g. patients), with features that represent occurrence of an event at a certain time.\n",
-    "If the event did not occur, it is \"censored\".\n",
-    "\n",
-    "Event data should take form of a `pandas.DataFrame`, with the following specifics:\n",
-    "* The index represents sample IDs and is a (single level) index that can be comprised of `int`s or `str`s (homogenous, not a mix of these).\n",
-    "* The columns of the dataframe represent the features, column names must be `str`.\n",
-    "* Column (feature) values must be of the form: `Tuple[<timestep>, bool]`.\n",
-    "    * The first element `<timestep>` may be `int`, `float` or `pandas.Timestep`-compatible format (homogenous per column).\n",
-    "    * The second element `bool` indicates whether the event occurred at this time (`True`) or the event feature is censored (`False`).\n",
-    "    * In case of censoring, the timestep should indicate the last time information about the sample was available. \n",
-    "\n",
-    "Other points to note:\n",
-    "* Sample IDs must be unique.\n",
-    "* Null values such as `numpy.nan` are not allowed allowed - indicate an event as censored (did not occur) instead."
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 4,
-   "metadata": {},
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "<class 'pandas.core.frame.DataFrame'>\n",
-      "Index: 3 entries, sample_0 to sample_2\n",
-      "Data columns (total 2 columns):\n",
-      " #   Column    Non-Null Count  Dtype \n",
-      "---  ------    --------------  ----- \n",
-      " 0   e_feat_0  3 non-null      object\n",
-      " 1   e_feat_1  3 non-null      object\n",
-      "dtypes: object(2)\n",
-      "memory usage: 72.0+ bytes\n"
-     ]
-    },
-    {
-     "data": {
-      "text/html": [
-       "<div>\n",
-       "<style scoped>\n",
-       "    .dataframe tbody tr th:only-of-type {\n",
-       "        vertical-align: middle;\n",
-       "    }\n",
-       "\n",
-       "    .dataframe tbody tr th {\n",
-       "        vertical-align: top;\n",
-       "    }\n",
-       "\n",
-       "    .dataframe thead th {\n",
-       "        text-align: right;\n",
-       "    }\n",
-       "</style>\n",
-       "<table border=\"1\" class=\"dataframe\">\n",
-       "  <thead>\n",
-       "    <tr style=\"text-align: right;\">\n",
-       "      <th></th>\n",
-       "      <th>e_feat_0</th>\n",
-       "      <th>e_feat_1</th>\n",
-       "    </tr>\n",
-       "  </thead>\n",
-       "  <tbody>\n",
-       "    <tr>\n",
-       "      <th>sample_0</th>\n",
-       "      <td>(10, True)</td>\n",
-       "      <td>(10, False)</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>sample_1</th>\n",
-       "      <td>(12, False)</td>\n",
-       "      <td>(10, False)</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>sample_2</th>\n",
-       "      <td>(13, True)</td>\n",
-       "      <td>(11, True)</td>\n",
-       "    </tr>\n",
-       "  </tbody>\n",
-       "</table>\n",
-       "</div>"
-      ],
-      "text/plain": [
-       "             e_feat_0     e_feat_1\n",
-       "sample_0   (10, True)  (10, False)\n",
-       "sample_1  (12, False)  (10, False)\n",
-       "sample_2   (13, True)   (11, True)"
-      ]
-     },
-     "execution_count": 4,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "# Create an event dataframe.\n",
-    "\n",
-    "event_df = pd.DataFrame(\n",
-    "    {\n",
-    "        \"e_feat_0\": [(10, True), (12, False), (13, True)],\n",
-    "        \"e_feat_1\": [(10, False), (10, False), (11, True)],\n",
-    "    },\n",
-    "    index=[\"sample_0\", \"sample_1\", \"sample_2\"],\n",
-    ")\n",
-    "\n",
-    "# Preview the dataframe:\n",
-    "event_df.info()\n",
-    "event_df"
-   ]
-  },
-  {
-   "attachments": {},
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "The data can also be initialised from a 2D `numpy` array (static, event) or a 3D `numpy` array (time series).\n",
-    "\n",
-    "`TODO: more info`"
-   ]
-  },
-  {
-   "attachments": {},
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "## Dataset\n",
-    "\n",
-    "The collection of data that represents the task at hand is a `Dataset`.\n",
-    "\n",
-    "A `Dataset` contains:\n",
-    "* Time series data (covariates),\n",
-    "* Static data (covariates), optional,\n",
-    "* Predictive data, which depends on the *task*.\n",
-    "    * This may contain *targets* and *treatments*.\n",
-    "\n",
-    "For example, for the *time-to-event analysis task* we create a dataset as follows.\n",
-    "\n",
-    "`TODO: more info`"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 5,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "TimeToEventAnalysisDataset(\n",
-       "    time_series=TimeSeriesSamples([3, *, 3]),\n",
-       "    static=StaticSamples([3, 2]),\n",
-       "    static=TimeToEventAnalysisTaskData(targets=EventSamples([3, 2]))\n",
-       ")"
-      ]
-     },
-     "execution_count": 5,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "from tempor.data.dataset import TimeToEventAnalysisDataset\n",
-    "\n",
-    "# Create a dataset of time-to-event analysis task:\n",
-    "data = TimeToEventAnalysisDataset(\n",
-    "    time_series=time_series_df,\n",
-    "    static=static_df,\n",
-    "    targets=event_df,\n",
-    ")\n",
-    "\n",
-    "# Preview dataset:\n",
-    "data"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 6,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "TimeSeriesSamples with data:\n",
-       "                     t_feat_0  t_feat_1 t_feat_2\n",
-       "sample_idx time_idx                             \n",
-       "sample_0   1               11       1.1        a\n",
-       "           2               12       1.2        b\n",
-       "           3               13       1.3        b\n",
-       "           4               14       NaN        c\n",
-       "sample_1   2               21       2.1        a\n",
-       "           4               22       2.2        a\n",
-       "sample_2   9               31       3.1        c"
-      ]
-     },
-     "execution_count": 6,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "data.time_series"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 7,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "StaticSamples with data:\n",
-       "            s_feat_0  s_feat_1\n",
-       "sample_idx                    \n",
-       "sample_0         100      -1.1\n",
-       "sample_1         200       NaN\n",
-       "sample_2         300      -1.3"
-      ]
-     },
-     "execution_count": 7,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "data.static"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 8,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "EventSamples with data:\n",
-       "               e_feat_0     e_feat_1\n",
-       "sample_idx                          \n",
-       "sample_0     (10, True)  (10, False)\n",
-       "sample_1    (12, False)  (10, False)\n",
-       "sample_2     (13, True)   (11, True)"
-      ]
-     },
-     "execution_count": 8,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "data.predictive.targets"
-   ]
-  }
- ],
- "metadata": {
-  "kernelspec": {
-   "display_name": "RE_py38_temporai",
-   "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.15"
-  },
-  "orig_nbformat": 4
- },
- "nbformat": 4,
- "nbformat_minor": 2
-}
diff --git a/tutorials/user_guide/tutorial01_plugins.ipynb b/tutorials/user_guide/tutorial01_plugins.ipynb
new file mode 100644
index 00000000..1ae57515
--- /dev/null
+++ b/tutorials/user_guide/tutorial01_plugins.ipynb
@@ -0,0 +1,407 @@
+{
+ "cells": [
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# User Guide Tutorial 01: Plugins\n",
+    "\n",
+    "This tutorial shows how to load TemporAI estimators (a.k.a. models), which are `Plugin`s."
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "*Skip the below cell if you are not on Google Colab / already have TemporAI installed:*"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "%pip install temporai\n",
+    "\n",
+    "# Or from the repo, for the latest version:\n",
+    "# %pip install git+https://github.com/vanderschaarlab/temporai.git"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Loading a `Plugin`\n",
+    "\n",
+    "All estimators (a.k.a. models) in TemporAI are implemented as `Plugin`s, for ease of extending the library.\n",
+    "\n",
+    "Each `Plugin` has two plugin-specific attributes: its `name` and `category`.\n",
+    "\n",
+    "You can load a plugin in two ways:\n",
+    "* From python module (file),\n",
+    "* From API.\n",
+    "\n",
+    "From its python module (file):"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Plugin class:\n",
+      "<class 'tempor.plugins.prediction.one_off.classification.plugin_nn_classifier.NeuralNetClassifier'>\n",
+      "\n",
+      "Plugin instance:\n",
+      "NeuralNetClassifier(\n",
+      "    name='nn_classifier',\n",
+      "    category='prediction.one_off.classification',\n",
+      "    params={\n",
+      "        'n_static_units_hidden': 100,\n",
+      "        'n_static_layers_hidden': 2,\n",
+      "        'n_temporal_units_hidden': 102,\n",
+      "        'n_temporal_layers_hidden': 2,\n",
+      "        'n_iter': 100,\n",
+      "        'mode': 'RNN',\n",
+      "        'n_iter_print': 10,\n",
+      "        'batch_size': 100,\n",
+      "        'lr': 0.001,\n",
+      "        'weight_decay': 0.001,\n",
+      "        'window_size': 1,\n",
+      "        'device': None,\n",
+      "        'dataloader_sampler': None,\n",
+      "        'dropout': 0.0,\n",
+      "        'nonlin': 'relu',\n",
+      "        'random_state': 0,\n",
+      "        'clipping_value': 1,\n",
+      "        'patience': 20,\n",
+      "        'train_ratio': 0.8\n",
+      "    }\n",
+      ")\n"
+     ]
+    }
+   ],
+   "source": [
+    "# Example of loading the prediction.one_off.classification.nn_classifier plugin from the module:\n",
+    "\n",
+    "from tempor.plugins.prediction.one_off.classification.plugin_nn_classifier import NeuralNetClassifier\n",
+    "\n",
+    "nn_classifier = NeuralNetClassifier(n_iter=100)\n",
+    "\n",
+    "print(f\"Plugin class:\\n{NeuralNetClassifier}\\n\")\n",
+    "print(f\"Plugin instance:\\n{nn_classifier}\")"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Or from the plugin API, as below.\n",
+    "\n",
+    "Note the `tempor.plugins.plugin_loader` object - this allows loading plugins by API."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Plugin class:\n",
+      "<class 'tempor.plugins.prediction.one_off.classification.plugin_nn_classifier.NeuralNetClassifier'>\n",
+      "\n",
+      "Plugin instance:\n",
+      "NeuralNetClassifier(\n",
+      "    name='nn_classifier',\n",
+      "    category='prediction.one_off.classification',\n",
+      "    params={\n",
+      "        'n_static_units_hidden': 100,\n",
+      "        'n_static_layers_hidden': 2,\n",
+      "        'n_temporal_units_hidden': 102,\n",
+      "        'n_temporal_layers_hidden': 2,\n",
+      "        'n_iter': 100,\n",
+      "        'mode': 'RNN',\n",
+      "        'n_iter_print': 10,\n",
+      "        'batch_size': 100,\n",
+      "        'lr': 0.001,\n",
+      "        'weight_decay': 0.001,\n",
+      "        'window_size': 1,\n",
+      "        'device': None,\n",
+      "        'dataloader_sampler': None,\n",
+      "        'dropout': 0.0,\n",
+      "        'nonlin': 'relu',\n",
+      "        'random_state': 0,\n",
+      "        'clipping_value': 1,\n",
+      "        'patience': 20,\n",
+      "        'train_ratio': 0.8\n",
+      "    }\n",
+      ")\n"
+     ]
+    }
+   ],
+   "source": [
+    "from tempor.plugins import plugin_loader\n",
+    "\n",
+    "# ^ Import the `plugin_loader`.\n",
+    "\n",
+    "nn_classifier_cls = plugin_loader.get_class(\"prediction.one_off.classification.nn_classifier\")\n",
+    "# ^ Get the plugin class from API by the fully-qualified plugin name.\n",
+    "#   The fully-qualified plugin name is \"<PLUGIN CATEGORY>.<PLUGIN NAME>\".\n",
+    "\n",
+    "nn_classifier = nn_classifier_cls(n_iter=100)\n",
+    "\n",
+    "print(f\"Plugin class:\\n{nn_classifier_cls}\\n\")\n",
+    "print(f\"Plugin instance:\\n{nn_classifier}\")"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "You can also get the plugin instance directly (rather than the class) from the API, as follows: "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Plugin instance:\n",
+      "NeuralNetClassifier(\n",
+      "    name='nn_classifier',\n",
+      "    category='prediction.one_off.classification',\n",
+      "    params={\n",
+      "        'n_static_units_hidden': 100,\n",
+      "        'n_static_layers_hidden': 2,\n",
+      "        'n_temporal_units_hidden': 102,\n",
+      "        'n_temporal_layers_hidden': 2,\n",
+      "        'n_iter': 100,\n",
+      "        'mode': 'RNN',\n",
+      "        'n_iter_print': 10,\n",
+      "        'batch_size': 100,\n",
+      "        'lr': 0.001,\n",
+      "        'weight_decay': 0.001,\n",
+      "        'window_size': 1,\n",
+      "        'device': None,\n",
+      "        'dataloader_sampler': None,\n",
+      "        'dropout': 0.0,\n",
+      "        'nonlin': 'relu',\n",
+      "        'random_state': 0,\n",
+      "        'clipping_value': 1,\n",
+      "        'patience': 20,\n",
+      "        'train_ratio': 0.8\n",
+      "    }\n",
+      ")\n"
+     ]
+    }
+   ],
+   "source": [
+    "nn_classifier = plugin_loader.get(\"prediction.one_off.classification.nn_classifier\", n_iter=100)\n",
+    "# ^ Using the `get` method rather than `get_class`.\n",
+    "#   The plugin initializer arguments (here, `n_iter=100`) can be provided as **kwargs here.\n",
+    "\n",
+    "print(f\"Plugin instance:\\n{nn_classifier}\")"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Listing all available `Plugin`s\n",
+    "\n",
+    "You can list all `Plugin`s currently available in TemporAI as follows:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\">{</span>\n",
+       "    <span style=\"color: #008000; text-decoration-color: #008000\">'prediction'</span>: <span style=\"font-weight: bold\">{</span>\n",
+       "        <span style=\"color: #008000; text-decoration-color: #008000\">'one_off'</span>: <span style=\"font-weight: bold\">{</span>\n",
+       "            <span style=\"color: #008000; text-decoration-color: #008000\">'classification'</span>: <span style=\"font-weight: bold\">[</span><span style=\"color: #008000; text-decoration-color: #008000\">'cde_classifier'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'ode_classifier'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'nn_classifier'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'laplace_ode_classifier'</span><span style=\"font-weight: bold\">]</span>,\n",
+       "            <span style=\"color: #008000; text-decoration-color: #008000\">'regression'</span>: <span style=\"font-weight: bold\">[</span><span style=\"color: #008000; text-decoration-color: #008000\">'laplace_ode_regressor'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'nn_regressor'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'ode_regressor'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'cde_regressor'</span><span style=\"font-weight: bold\">]</span>\n",
+       "        <span style=\"font-weight: bold\">}</span>,\n",
+       "        <span style=\"color: #008000; text-decoration-color: #008000\">'temporal'</span>: <span style=\"font-weight: bold\">{</span><span style=\"color: #008000; text-decoration-color: #008000\">'classification'</span>: <span style=\"font-weight: bold\">[</span><span style=\"color: #008000; text-decoration-color: #008000\">'seq2seq_classifier'</span><span style=\"font-weight: bold\">]</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'regression'</span>: <span style=\"font-weight: bold\">[</span><span style=\"color: #008000; text-decoration-color: #008000\">'seq2seq_regressor'</span><span style=\"font-weight: bold\">]}</span>\n",
+       "    <span style=\"font-weight: bold\">}</span>,\n",
+       "    <span style=\"color: #008000; text-decoration-color: #008000\">'preprocessing'</span>: <span style=\"font-weight: bold\">{</span>\n",
+       "        <span style=\"color: #008000; text-decoration-color: #008000\">'imputation'</span>: <span style=\"font-weight: bold\">{</span><span style=\"color: #008000; text-decoration-color: #008000\">'static'</span>: <span style=\"font-weight: bold\">[</span><span style=\"color: #008000; text-decoration-color: #008000\">'static_imputation'</span><span style=\"font-weight: bold\">]</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'temporal'</span>: <span style=\"font-weight: bold\">[</span><span style=\"color: #008000; text-decoration-color: #008000\">'ffill'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'bfill'</span><span style=\"font-weight: bold\">]}</span>,\n",
+       "        <span style=\"color: #008000; text-decoration-color: #008000\">'nop'</span>: <span style=\"font-weight: bold\">[</span><span style=\"color: #008000; text-decoration-color: #008000\">'nop_transformer'</span><span style=\"font-weight: bold\">]</span>,\n",
+       "        <span style=\"color: #008000; text-decoration-color: #008000\">'scaling'</span>: <span style=\"font-weight: bold\">{</span>\n",
+       "            <span style=\"color: #008000; text-decoration-color: #008000\">'static'</span>: <span style=\"font-weight: bold\">[</span><span style=\"color: #008000; text-decoration-color: #008000\">'static_minmax_scaler'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'static_standard_scaler'</span><span style=\"font-weight: bold\">]</span>,\n",
+       "            <span style=\"color: #008000; text-decoration-color: #008000\">'temporal'</span>: <span style=\"font-weight: bold\">[</span><span style=\"color: #008000; text-decoration-color: #008000\">'ts_minmax_scaler'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'ts_standard_scaler'</span><span style=\"font-weight: bold\">]</span>\n",
+       "        <span style=\"font-weight: bold\">}</span>\n",
+       "    <span style=\"font-weight: bold\">}</span>,\n",
+       "    <span style=\"color: #008000; text-decoration-color: #008000\">'time_to_event'</span>: <span style=\"font-weight: bold\">[</span><span style=\"color: #008000; text-decoration-color: #008000\">'ts_coxph'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'ts_xgb'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'dynamic_deephit'</span><span style=\"font-weight: bold\">]</span>,\n",
+       "    <span style=\"color: #008000; text-decoration-color: #008000\">'treatments'</span>: <span style=\"font-weight: bold\">{</span>\n",
+       "        <span style=\"color: #008000; text-decoration-color: #008000\">'one_off'</span>: <span style=\"font-weight: bold\">{</span><span style=\"color: #008000; text-decoration-color: #008000\">'regression'</span>: <span style=\"font-weight: bold\">[</span><span style=\"color: #008000; text-decoration-color: #008000\">'synctwin_regressor'</span><span style=\"font-weight: bold\">]}</span>,\n",
+       "        <span style=\"color: #008000; text-decoration-color: #008000\">'temporal'</span>: <span style=\"font-weight: bold\">{</span><span style=\"color: #008000; text-decoration-color: #008000\">'classification'</span>: <span style=\"font-weight: bold\">[</span><span style=\"color: #008000; text-decoration-color: #008000\">'crn_classifier'</span><span style=\"font-weight: bold\">]</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'regression'</span>: <span style=\"font-weight: bold\">[</span><span style=\"color: #008000; text-decoration-color: #008000\">'crn_regressor'</span><span style=\"font-weight: bold\">]}</span>\n",
+       "    <span style=\"font-weight: bold\">}</span>\n",
+       "<span style=\"font-weight: bold\">}</span>\n",
+       "</pre>\n"
+      ],
+      "text/plain": [
+       "\u001b[1m{\u001b[0m\n",
+       "    \u001b[32m'prediction'\u001b[0m: \u001b[1m{\u001b[0m\n",
+       "        \u001b[32m'one_off'\u001b[0m: \u001b[1m{\u001b[0m\n",
+       "            \u001b[32m'classification'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'cde_classifier'\u001b[0m, \u001b[32m'ode_classifier'\u001b[0m, \u001b[32m'nn_classifier'\u001b[0m, \u001b[32m'laplace_ode_classifier'\u001b[0m\u001b[1m]\u001b[0m,\n",
+       "            \u001b[32m'regression'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'laplace_ode_regressor'\u001b[0m, \u001b[32m'nn_regressor'\u001b[0m, \u001b[32m'ode_regressor'\u001b[0m, \u001b[32m'cde_regressor'\u001b[0m\u001b[1m]\u001b[0m\n",
+       "        \u001b[1m}\u001b[0m,\n",
+       "        \u001b[32m'temporal'\u001b[0m: \u001b[1m{\u001b[0m\u001b[32m'classification'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'seq2seq_classifier'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'regression'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'seq2seq_regressor'\u001b[0m\u001b[1m]\u001b[0m\u001b[1m}\u001b[0m\n",
+       "    \u001b[1m}\u001b[0m,\n",
+       "    \u001b[32m'preprocessing'\u001b[0m: \u001b[1m{\u001b[0m\n",
+       "        \u001b[32m'imputation'\u001b[0m: \u001b[1m{\u001b[0m\u001b[32m'static'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'static_imputation'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'temporal'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'ffill'\u001b[0m, \u001b[32m'bfill'\u001b[0m\u001b[1m]\u001b[0m\u001b[1m}\u001b[0m,\n",
+       "        \u001b[32m'nop'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'nop_transformer'\u001b[0m\u001b[1m]\u001b[0m,\n",
+       "        \u001b[32m'scaling'\u001b[0m: \u001b[1m{\u001b[0m\n",
+       "            \u001b[32m'static'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'static_minmax_scaler'\u001b[0m, \u001b[32m'static_standard_scaler'\u001b[0m\u001b[1m]\u001b[0m,\n",
+       "            \u001b[32m'temporal'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'ts_minmax_scaler'\u001b[0m, \u001b[32m'ts_standard_scaler'\u001b[0m\u001b[1m]\u001b[0m\n",
+       "        \u001b[1m}\u001b[0m\n",
+       "    \u001b[1m}\u001b[0m,\n",
+       "    \u001b[32m'time_to_event'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'ts_coxph'\u001b[0m, \u001b[32m'ts_xgb'\u001b[0m, \u001b[32m'dynamic_deephit'\u001b[0m\u001b[1m]\u001b[0m,\n",
+       "    \u001b[32m'treatments'\u001b[0m: \u001b[1m{\u001b[0m\n",
+       "        \u001b[32m'one_off'\u001b[0m: \u001b[1m{\u001b[0m\u001b[32m'regression'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'synctwin_regressor'\u001b[0m\u001b[1m]\u001b[0m\u001b[1m}\u001b[0m,\n",
+       "        \u001b[32m'temporal'\u001b[0m: \u001b[1m{\u001b[0m\u001b[32m'classification'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'crn_classifier'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'regression'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'crn_regressor'\u001b[0m\u001b[1m]\u001b[0m\u001b[1m}\u001b[0m\n",
+       "    \u001b[1m}\u001b[0m\n",
+       "\u001b[1m}\u001b[0m\n"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "from tempor.plugins import plugin_loader\n",
+    "\n",
+    "# Use plugin_loader.list():\n",
+    "all_plugins = plugin_loader.list()\n",
+    "\n",
+    "# Displaying using pretty print here for clarity:\n",
+    "from rich.pretty import pprint\n",
+    "\n",
+    "pprint(all_plugins, indent_guides=False)"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Note that plugin categories are hierarchical (nested).\n",
+    "\n",
+    "To quickly view the plugin fully qualified name (`fqn`) for all plugins, use `plugin_loader.list_fqns()`.\n",
+    "\n",
+    "These are the names to use in `plugin_loader.{get,get_class}` calls."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 17,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['prediction.one_off.classification.cde_classifier',\n",
+       " 'prediction.one_off.classification.ode_classifier',\n",
+       " 'prediction.one_off.classification.nn_classifier',\n",
+       " 'prediction.one_off.classification.laplace_ode_classifier',\n",
+       " 'prediction.one_off.regression.laplace_ode_regressor',\n",
+       " 'prediction.one_off.regression.nn_regressor',\n",
+       " 'prediction.one_off.regression.ode_regressor',\n",
+       " 'prediction.one_off.regression.cde_regressor',\n",
+       " 'prediction.temporal.classification.seq2seq_classifier',\n",
+       " 'prediction.temporal.regression.seq2seq_regressor',\n",
+       " 'preprocessing.imputation.static.static_imputation',\n",
+       " 'preprocessing.imputation.temporal.ffill',\n",
+       " 'preprocessing.imputation.temporal.bfill',\n",
+       " 'preprocessing.nop.nop_transformer',\n",
+       " 'preprocessing.scaling.static.static_minmax_scaler',\n",
+       " 'preprocessing.scaling.static.static_standard_scaler',\n",
+       " 'preprocessing.scaling.temporal.ts_minmax_scaler',\n",
+       " 'preprocessing.scaling.temporal.ts_standard_scaler',\n",
+       " 'time_to_event.ts_coxph',\n",
+       " 'time_to_event.ts_xgb',\n",
+       " 'time_to_event.dynamic_deephit',\n",
+       " 'treatments.one_off.regression.synctwin_regressor',\n",
+       " 'treatments.temporal.classification.crn_classifier',\n",
+       " 'treatments.temporal.regression.crn_regressor']"
+      ]
+     },
+     "execution_count": 17,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "plugin_loader.list_fqns()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## 🎉 Congratulations!\n",
+    "\n",
+    "Congratulations on completing this notebook tutorial! If you enjoyed this and would like to join the movement towards *Machine learning and AI for Medicine*, you can do so in the following ways!\n",
+    "\n",
+    "\n",
+    "\n",
+    "### ⭐ Star [TemporAI](https://github.com/vanderschaarlab/temporai) on GitHub\n",
+    "\n",
+    "- The easiest way to help our community is by just starring the repos! This helps raise awareness of the tools we're building.\n",
+    "\n",
+    "\n",
+    "\n",
+    "### Check out other projects from [vanderschaarlab](https://github.com/vanderschaarlab)\n",
+    "- 📝 [HyperImpute](https://github.com/vanderschaarlab/hyperimpute)\n",
+    "- 📊 [AutoPrognosis](https://github.com/vanderschaarlab/autoprognosis)\n",
+    "- 🤖 [SynthCity](https://github.com/vanderschaarlab/synthcity)\n",
+    " "
+   ]
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "RE_py38_temporai",
+   "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.15"
+  },
+  "orig_nbformat": 4
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/tutorials/user_guide/tutorial02_imputation.ipynb b/tutorials/user_guide/tutorial02_imputation.ipynb
new file mode 100644
index 00000000..a83b271b
--- /dev/null
+++ b/tutorials/user_guide/tutorial02_imputation.ipynb
@@ -0,0 +1,876 @@
+{
+ "cells": [
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# User Guide Tutorial 02: Preprocessing › Imputation\n",
+    "\n",
+    "This tutorial shows how to use TemporAI `preprocessing.imputation` plugins."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "*Skip the below cell if you are not on Google Colab / already have TemporAI installed:*"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "%pip install temporai\n",
+    "\n",
+    "# Or from the repo, for the latest version:\n",
+    "# %pip install git+https://github.com/vanderschaarlab/temporai.git"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## All `preprocessing.imputation` plugins\n",
+    "\n",
+    "To see all the relevant plugins:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{'static': ['static_imputation'], 'temporal': ['ffill', 'bfill']}"
+      ]
+     },
+     "execution_count": 2,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "from tempor.plugins import plugin_loader\n",
+    "\n",
+    "plugin_loader.list()[\"preprocessing\"][\"imputation\"]"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Using a static data imputation plugin"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "OneOffPredictionDataset(\n",
+      "    time_series=TimeSeriesSamples([100, *, 5]),\n",
+      "    static=StaticSamples([100, 4]),\n",
+      "    predictive=OneOffPredictionTaskData(targets=StaticSamples([100, 1]))\n",
+      ")\n",
+      "StaticOnlyImputer(\n",
+      "    name='static_imputation',\n",
+      "    category='preprocessing.imputation.static',\n",
+      "    params={}\n",
+      ")\n"
+     ]
+    }
+   ],
+   "source": [
+    "from tempor.utils.dataloaders import SineDataLoader\n",
+    "from tempor.plugins import plugin_loader\n",
+    "\n",
+    "dataset = SineDataLoader(with_missing=True, random_state=42).load()\n",
+    "print(dataset)\n",
+    "\n",
+    "model = plugin_loader.get(\"preprocessing.imputation.static.static_imputation\", static_imputer=\"mean\")\n",
+    "print(model)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Missing value count: 40\n"
+     ]
+    },
+    {
+     "data": {
+      "text/html": [
+       "<p><span style=\"font-family: monospace;\">StaticSamples</span> with data:</p><div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th>0</th>\n",
+       "      <th>1</th>\n",
+       "      <th>2</th>\n",
+       "      <th>3</th>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_idx</th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th>0</th>\n",
+       "      <td>0.374540</td>\n",
+       "      <td>0.950714</td>\n",
+       "      <td>0.731994</td>\n",
+       "      <td>0.598658</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>1</th>\n",
+       "      <td>0.156019</td>\n",
+       "      <td>0.155995</td>\n",
+       "      <td>0.058084</td>\n",
+       "      <td>0.866176</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>2</th>\n",
+       "      <td>0.601115</td>\n",
+       "      <td>0.708073</td>\n",
+       "      <td>0.020584</td>\n",
+       "      <td>0.969910</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>3</th>\n",
+       "      <td>0.832443</td>\n",
+       "      <td>NaN</td>\n",
+       "      <td>0.181825</td>\n",
+       "      <td>0.183405</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>0.304242</td>\n",
+       "      <td>0.524756</td>\n",
+       "      <td>0.431945</td>\n",
+       "      <td>0.291229</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>...</th>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>95</th>\n",
+       "      <td>NaN</td>\n",
+       "      <td>0.696737</td>\n",
+       "      <td>0.628943</td>\n",
+       "      <td>NaN</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>96</th>\n",
+       "      <td>0.735071</td>\n",
+       "      <td>0.803481</td>\n",
+       "      <td>0.282035</td>\n",
+       "      <td>NaN</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>97</th>\n",
+       "      <td>0.750615</td>\n",
+       "      <td>0.806835</td>\n",
+       "      <td>0.990505</td>\n",
+       "      <td>0.412618</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>98</th>\n",
+       "      <td>0.372018</td>\n",
+       "      <td>0.776413</td>\n",
+       "      <td>0.340804</td>\n",
+       "      <td>0.930757</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>99</th>\n",
+       "      <td>0.858413</td>\n",
+       "      <td>0.428994</td>\n",
+       "      <td>0.750871</td>\n",
+       "      <td>0.754543</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "<p>100 rows × 4 columns</p>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "StaticSamples with data:\n",
+       "                   0         1         2         3\n",
+       "sample_idx                                        \n",
+       "0           0.374540  0.950714  0.731994  0.598658\n",
+       "1           0.156019  0.155995  0.058084  0.866176\n",
+       "2           0.601115  0.708073  0.020584  0.969910\n",
+       "3           0.832443       NaN  0.181825  0.183405\n",
+       "4           0.304242  0.524756  0.431945  0.291229\n",
+       "...              ...       ...       ...       ...\n",
+       "95               NaN  0.696737  0.628943       NaN\n",
+       "96          0.735071  0.803481  0.282035       NaN\n",
+       "97          0.750615  0.806835  0.990505  0.412618\n",
+       "98          0.372018  0.776413  0.340804  0.930757\n",
+       "99          0.858413  0.428994  0.750871  0.754543\n",
+       "\n",
+       "[100 rows x 4 columns]"
+      ]
+     },
+     "execution_count": 4,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# Note missingness in static data.\n",
+    "\n",
+    "print(\"Missing value count:\", dataset.static.dataframe().isnull().sum().sum())  # type: ignore\n",
+    "\n",
+    "dataset.static"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Missing value count: 0\n"
+     ]
+    },
+    {
+     "data": {
+      "text/html": [
+       "<p><span style=\"font-family: monospace;\">StaticSamples</span> with data:</p><div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th>0</th>\n",
+       "      <th>1</th>\n",
+       "      <th>2</th>\n",
+       "      <th>3</th>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_idx</th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th>0</th>\n",
+       "      <td>0.374540</td>\n",
+       "      <td>0.950714</td>\n",
+       "      <td>0.731994</td>\n",
+       "      <td>0.598658</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>1</th>\n",
+       "      <td>0.156019</td>\n",
+       "      <td>0.155995</td>\n",
+       "      <td>0.058084</td>\n",
+       "      <td>0.866176</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>2</th>\n",
+       "      <td>0.601115</td>\n",
+       "      <td>0.708073</td>\n",
+       "      <td>0.020584</td>\n",
+       "      <td>0.969910</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>3</th>\n",
+       "      <td>0.832443</td>\n",
+       "      <td>0.502075</td>\n",
+       "      <td>0.181825</td>\n",
+       "      <td>0.183405</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>0.304242</td>\n",
+       "      <td>0.524756</td>\n",
+       "      <td>0.431945</td>\n",
+       "      <td>0.291229</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>...</th>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>95</th>\n",
+       "      <td>0.499558</td>\n",
+       "      <td>0.696737</td>\n",
+       "      <td>0.628943</td>\n",
+       "      <td>0.483415</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>96</th>\n",
+       "      <td>0.735071</td>\n",
+       "      <td>0.803481</td>\n",
+       "      <td>0.282035</td>\n",
+       "      <td>0.483415</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>97</th>\n",
+       "      <td>0.750615</td>\n",
+       "      <td>0.806835</td>\n",
+       "      <td>0.990505</td>\n",
+       "      <td>0.412618</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>98</th>\n",
+       "      <td>0.372018</td>\n",
+       "      <td>0.776413</td>\n",
+       "      <td>0.340804</td>\n",
+       "      <td>0.930757</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>99</th>\n",
+       "      <td>0.858413</td>\n",
+       "      <td>0.428994</td>\n",
+       "      <td>0.750871</td>\n",
+       "      <td>0.754543</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "<p>100 rows × 4 columns</p>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "StaticSamples with data:\n",
+       "                   0         1         2         3\n",
+       "sample_idx                                        \n",
+       "0           0.374540  0.950714  0.731994  0.598658\n",
+       "1           0.156019  0.155995  0.058084  0.866176\n",
+       "2           0.601115  0.708073  0.020584  0.969910\n",
+       "3           0.832443  0.502075  0.181825  0.183405\n",
+       "4           0.304242  0.524756  0.431945  0.291229\n",
+       "...              ...       ...       ...       ...\n",
+       "95          0.499558  0.696737  0.628943  0.483415\n",
+       "96          0.735071  0.803481  0.282035  0.483415\n",
+       "97          0.750615  0.806835  0.990505  0.412618\n",
+       "98          0.372018  0.776413  0.340804  0.930757\n",
+       "99          0.858413  0.428994  0.750871  0.754543\n",
+       "\n",
+       "[100 rows x 4 columns]"
+      ]
+     },
+     "execution_count": 5,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# Note no more missingness in static data.\n",
+    "\n",
+    "dataset = model.fit_transform(dataset)  # Or call fit() then transform().\n",
+    "\n",
+    "print(\"Missing value count:\", dataset.static.dataframe().isnull().sum().sum())  # type: ignore\n",
+    "\n",
+    "dataset.static"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Using a temporal data imputation plugin"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "OneOffPredictionDataset(\n",
+      "    time_series=TimeSeriesSamples([100, *, 5]),\n",
+      "    static=StaticSamples([100, 4]),\n",
+      "    predictive=OneOffPredictionTaskData(targets=StaticSamples([100, 1]))\n",
+      ")\n",
+      "BFillImputer(\n",
+      "    name='bfill',\n",
+      "    category='preprocessing.imputation.temporal',\n",
+      "    params={}\n",
+      ")\n"
+     ]
+    }
+   ],
+   "source": [
+    "from tempor.utils.dataloaders import SineDataLoader\n",
+    "from tempor.plugins import plugin_loader\n",
+    "\n",
+    "dataset = SineDataLoader(with_missing=True, random_state=42).load()\n",
+    "print(dataset)\n",
+    "\n",
+    "model = plugin_loader.get(\"preprocessing.imputation.temporal.bfill\")\n",
+    "print(model)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Missing value count: 500\n"
+     ]
+    },
+    {
+     "data": {
+      "text/html": [
+       "<p><span style=\"font-family: monospace;\">TimeSeriesSamples</span> with data:</p><div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th>0</th>\n",
+       "      <th>1</th>\n",
+       "      <th>2</th>\n",
+       "      <th>3</th>\n",
+       "      <th>4</th>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_idx</th>\n",
+       "      <th>time_idx</th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"5\" valign=\"top\">0</th>\n",
+       "      <th>0</th>\n",
+       "      <td>-0.955338</td>\n",
+       "      <td>0.016053</td>\n",
+       "      <td>-0.995752</td>\n",
+       "      <td>0.948138</td>\n",
+       "      <td>0.738158</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>1</th>\n",
+       "      <td>-0.896718</td>\n",
+       "      <td>0.717189</td>\n",
+       "      <td>-0.497625</td>\n",
+       "      <td>0.962001</td>\n",
+       "      <td>0.968258</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>2</th>\n",
+       "      <td>-0.346466</td>\n",
+       "      <td>0.999920</td>\n",
+       "      <td>0.423104</td>\n",
+       "      <td>0.639780</td>\n",
+       "      <td>0.972469</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>3</th>\n",
+       "      <td>0.393737</td>\n",
+       "      <td>0.699299</td>\n",
+       "      <td>0.984517</td>\n",
+       "      <td>0.094046</td>\n",
+       "      <td>0.749807</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>0.918072</td>\n",
+       "      <td>-0.009290</td>\n",
+       "      <td>NaN</td>\n",
+       "      <td>NaN</td>\n",
+       "      <td>NaN</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>...</th>\n",
+       "      <th>...</th>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"5\" valign=\"top\">99</th>\n",
+       "      <th>5</th>\n",
+       "      <td>0.904284</td>\n",
+       "      <td>-0.939985</td>\n",
+       "      <td>0.994099</td>\n",
+       "      <td>-0.984349</td>\n",
+       "      <td>0.688521</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>6</th>\n",
+       "      <td>0.990911</td>\n",
+       "      <td>-0.518593</td>\n",
+       "      <td>0.908681</td>\n",
+       "      <td>-0.801263</td>\n",
+       "      <td>0.813486</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>7</th>\n",
+       "      <td>0.757745</td>\n",
+       "      <td>0.131791</td>\n",
+       "      <td>NaN</td>\n",
+       "      <td>-0.110629</td>\n",
+       "      <td>0.908965</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>8</th>\n",
+       "      <td>NaN</td>\n",
+       "      <td>0.723981</td>\n",
+       "      <td>0.476023</td>\n",
+       "      <td>0.650082</td>\n",
+       "      <td>0.971498</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>9</th>\n",
+       "      <td>-0.288052</td>\n",
+       "      <td>0.996486</td>\n",
+       "      <td>0.173255</td>\n",
+       "      <td>0.999008</td>\n",
+       "      <td>0.998817</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "<p>1000 rows × 5 columns</p>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "TimeSeriesSamples with data:\n",
+       "                            0         1         2         3         4\n",
+       "sample_idx time_idx                                                  \n",
+       "0          0        -0.955338  0.016053 -0.995752  0.948138  0.738158\n",
+       "           1        -0.896718  0.717189 -0.497625  0.962001  0.968258\n",
+       "           2        -0.346466  0.999920  0.423104  0.639780  0.972469\n",
+       "           3         0.393737  0.699299  0.984517  0.094046  0.749807\n",
+       "           4         0.918072 -0.009290       NaN       NaN       NaN\n",
+       "...                       ...       ...       ...       ...       ...\n",
+       "99         5         0.904284 -0.939985  0.994099 -0.984349  0.688521\n",
+       "           6         0.990911 -0.518593  0.908681 -0.801263  0.813486\n",
+       "           7         0.757745  0.131791       NaN -0.110629  0.908965\n",
+       "           8              NaN  0.723981  0.476023  0.650082  0.971498\n",
+       "           9        -0.288052  0.996486  0.173255  0.999008  0.998817\n",
+       "\n",
+       "[1000 rows x 5 columns]"
+      ]
+     },
+     "execution_count": 7,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# Note missingness in temporal data.\n",
+    "\n",
+    "print(\"Missing value count:\", dataset.time_series.dataframe().isnull().sum().sum())\n",
+    "\n",
+    "dataset.time_series"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Missing value count: 0\n"
+     ]
+    },
+    {
+     "data": {
+      "text/html": [
+       "<p><span style=\"font-family: monospace;\">TimeSeriesSamples</span> with data:</p><div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th>0</th>\n",
+       "      <th>1</th>\n",
+       "      <th>2</th>\n",
+       "      <th>3</th>\n",
+       "      <th>4</th>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_idx</th>\n",
+       "      <th>time_idx</th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"5\" valign=\"top\">0</th>\n",
+       "      <th>0</th>\n",
+       "      <td>-0.955338</td>\n",
+       "      <td>0.016053</td>\n",
+       "      <td>-0.995752</td>\n",
+       "      <td>0.948138</td>\n",
+       "      <td>0.738158</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>1</th>\n",
+       "      <td>-0.896718</td>\n",
+       "      <td>0.717189</td>\n",
+       "      <td>-0.497625</td>\n",
+       "      <td>0.962001</td>\n",
+       "      <td>0.968258</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>2</th>\n",
+       "      <td>-0.346466</td>\n",
+       "      <td>0.999920</td>\n",
+       "      <td>0.423104</td>\n",
+       "      <td>0.639780</td>\n",
+       "      <td>0.972469</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>3</th>\n",
+       "      <td>0.393737</td>\n",
+       "      <td>0.699299</td>\n",
+       "      <td>0.984517</td>\n",
+       "      <td>0.094046</td>\n",
+       "      <td>0.749807</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>0.918072</td>\n",
+       "      <td>-0.009290</td>\n",
+       "      <td>-0.167662</td>\n",
+       "      <td>-0.893854</td>\n",
+       "      <td>-0.127538</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>...</th>\n",
+       "      <th>...</th>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"5\" valign=\"top\">99</th>\n",
+       "      <th>5</th>\n",
+       "      <td>0.904284</td>\n",
+       "      <td>-0.939985</td>\n",
+       "      <td>0.994099</td>\n",
+       "      <td>-0.984349</td>\n",
+       "      <td>0.688521</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>6</th>\n",
+       "      <td>0.990911</td>\n",
+       "      <td>-0.518593</td>\n",
+       "      <td>0.908681</td>\n",
+       "      <td>-0.801263</td>\n",
+       "      <td>0.813486</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>7</th>\n",
+       "      <td>0.757745</td>\n",
+       "      <td>0.131791</td>\n",
+       "      <td>0.476023</td>\n",
+       "      <td>-0.110629</td>\n",
+       "      <td>0.908965</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>8</th>\n",
+       "      <td>-0.288052</td>\n",
+       "      <td>0.723981</td>\n",
+       "      <td>0.476023</td>\n",
+       "      <td>0.650082</td>\n",
+       "      <td>0.971498</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>9</th>\n",
+       "      <td>-0.288052</td>\n",
+       "      <td>0.996486</td>\n",
+       "      <td>0.173255</td>\n",
+       "      <td>0.999008</td>\n",
+       "      <td>0.998817</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "<p>1000 rows × 5 columns</p>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "TimeSeriesSamples with data:\n",
+       "                            0         1         2         3         4\n",
+       "sample_idx time_idx                                                  \n",
+       "0          0        -0.955338  0.016053 -0.995752  0.948138  0.738158\n",
+       "           1        -0.896718  0.717189 -0.497625  0.962001  0.968258\n",
+       "           2        -0.346466  0.999920  0.423104  0.639780  0.972469\n",
+       "           3         0.393737  0.699299  0.984517  0.094046  0.749807\n",
+       "           4         0.918072 -0.009290 -0.167662 -0.893854 -0.127538\n",
+       "...                       ...       ...       ...       ...       ...\n",
+       "99         5         0.904284 -0.939985  0.994099 -0.984349  0.688521\n",
+       "           6         0.990911 -0.518593  0.908681 -0.801263  0.813486\n",
+       "           7         0.757745  0.131791  0.476023 -0.110629  0.908965\n",
+       "           8        -0.288052  0.723981  0.476023  0.650082  0.971498\n",
+       "           9        -0.288052  0.996486  0.173255  0.999008  0.998817\n",
+       "\n",
+       "[1000 rows x 5 columns]"
+      ]
+     },
+     "execution_count": 8,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# Note no more missingness in temporal data.\n",
+    "\n",
+    "dataset = model.fit_transform(dataset)  # Or call fit() then transform().\n",
+    "\n",
+    "print(\"Missing value count:\", dataset.time_series.dataframe().isnull().sum().sum())\n",
+    "\n",
+    "dataset.time_series"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## 🎉 Congratulations!\n",
+    "\n",
+    "Congratulations on completing this notebook tutorial! If you enjoyed this and would like to join the movement towards *Machine learning and AI for Medicine*, you can do so in the following ways!\n",
+    "\n",
+    "\n",
+    "\n",
+    "### ⭐ Star [TemporAI](https://github.com/vanderschaarlab/temporai) on GitHub\n",
+    "\n",
+    "- The easiest way to help our community is by just starring the repos! This helps raise awareness of the tools we're building.\n",
+    "\n",
+    "\n",
+    "\n",
+    "### Check out other projects from [vanderschaarlab](https://github.com/vanderschaarlab)\n",
+    "- 📝 [HyperImpute](https://github.com/vanderschaarlab/hyperimpute)\n",
+    "- 📊 [AutoPrognosis](https://github.com/vanderschaarlab/autoprognosis)\n",
+    "- 🤖 [SynthCity](https://github.com/vanderschaarlab/synthcity)\n",
+    " "
+   ]
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "RE_py38_temporai",
+   "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.15"
+  },
+  "orig_nbformat": 4
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/tutorials/user_guide/tutorial03_scaling.ipynb b/tutorials/user_guide/tutorial03_scaling.ipynb
new file mode 100644
index 00000000..81cdb048
--- /dev/null
+++ b/tutorials/user_guide/tutorial03_scaling.ipynb
@@ -0,0 +1,1141 @@
+{
+ "cells": [
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# User Guide Tutorial 03: Preprocessing › Scaling\n",
+    "\n",
+    "This tutorial shows how to use TemporAI `preprocessing.scaling` plugins."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "*Skip the below cell if you are not on Google Colab / already have TemporAI installed:*"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "%pip install temporai\n",
+    "\n",
+    "# Or from the repo, for the latest version:\n",
+    "# %pip install git+https://github.com/vanderschaarlab/temporai.git"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## All `preprocessing.scaling` plugins\n",
+    "\n",
+    "To see all the relevant plugins:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{'static': ['static_minmax_scaler', 'static_standard_scaler'],\n",
+       " 'temporal': ['ts_minmax_scaler', 'ts_standard_scaler']}"
+      ]
+     },
+     "execution_count": 2,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "from tempor.plugins import plugin_loader\n",
+    "\n",
+    "plugin_loader.list()[\"preprocessing\"][\"scaling\"]"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Using a static data scaling plugin"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "OneOffPredictionDataset(\n",
+      "    time_series=TimeSeriesSamples([100, *, 5]),\n",
+      "    static=StaticSamples([100, 4]),\n",
+      "    predictive=OneOffPredictionTaskData(targets=StaticSamples([100, 1]))\n",
+      ")\n",
+      "StaticMinMaxScaler(\n",
+      "    name='static_minmax_scaler',\n",
+      "    category='preprocessing.scaling.static',\n",
+      "    params={}\n",
+      ")\n"
+     ]
+    }
+   ],
+   "source": [
+    "from tempor.utils.dataloaders import SineDataLoader\n",
+    "from tempor.plugins import plugin_loader\n",
+    "\n",
+    "dataset = SineDataLoader(static_scale=5.0, random_state=42).load()\n",
+    "print(dataset)\n",
+    "\n",
+    "model = plugin_loader.get(\"preprocessing.scaling.static.static_minmax_scaler\", static_imputer=\"mean\")\n",
+    "print(model)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Min, max values per feature:\n"
+     ]
+    },
+    {
+     "data": {
+      "text/html": [
+       "<div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th>min</th>\n",
+       "      <th>max</th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th>0</th>\n",
+       "      <td>0.025308</td>\n",
+       "      <td>4.818100</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>1</th>\n",
+       "      <td>0.045985</td>\n",
+       "      <td>4.950269</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>2</th>\n",
+       "      <td>0.102922</td>\n",
+       "      <td>4.952526</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>3</th>\n",
+       "      <td>0.082939</td>\n",
+       "      <td>4.858910</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "        min       max\n",
+       "0  0.025308  4.818100\n",
+       "1  0.045985  4.950269\n",
+       "2  0.102922  4.952526\n",
+       "3  0.082939  4.858910"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<p><span style=\"font-family: monospace;\">StaticSamples</span> with data:</p><div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th>0</th>\n",
+       "      <th>1</th>\n",
+       "      <th>2</th>\n",
+       "      <th>3</th>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_idx</th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th>0</th>\n",
+       "      <td>1.872701</td>\n",
+       "      <td>4.753572</td>\n",
+       "      <td>3.659970</td>\n",
+       "      <td>2.993292</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>1</th>\n",
+       "      <td>0.780093</td>\n",
+       "      <td>0.779973</td>\n",
+       "      <td>0.290418</td>\n",
+       "      <td>4.330881</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>2</th>\n",
+       "      <td>3.005575</td>\n",
+       "      <td>3.540363</td>\n",
+       "      <td>0.102922</td>\n",
+       "      <td>4.849549</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>3</th>\n",
+       "      <td>4.162213</td>\n",
+       "      <td>1.061696</td>\n",
+       "      <td>0.909125</td>\n",
+       "      <td>0.917023</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>1.521211</td>\n",
+       "      <td>2.623782</td>\n",
+       "      <td>2.159725</td>\n",
+       "      <td>1.456146</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>...</th>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>95</th>\n",
+       "      <td>0.590824</td>\n",
+       "      <td>3.483686</td>\n",
+       "      <td>3.144714</td>\n",
+       "      <td>4.387360</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>96</th>\n",
+       "      <td>3.675355</td>\n",
+       "      <td>4.017405</td>\n",
+       "      <td>1.410173</td>\n",
+       "      <td>0.887198</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>97</th>\n",
+       "      <td>3.753074</td>\n",
+       "      <td>4.034174</td>\n",
+       "      <td>4.952526</td>\n",
+       "      <td>2.063088</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>98</th>\n",
+       "      <td>1.860090</td>\n",
+       "      <td>3.882065</td>\n",
+       "      <td>1.704018</td>\n",
+       "      <td>4.653787</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>99</th>\n",
+       "      <td>4.292064</td>\n",
+       "      <td>2.144970</td>\n",
+       "      <td>3.754355</td>\n",
+       "      <td>3.772714</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "<p>100 rows × 4 columns</p>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "StaticSamples with data:\n",
+       "                   0         1         2         3\n",
+       "sample_idx                                        \n",
+       "0           1.872701  4.753572  3.659970  2.993292\n",
+       "1           0.780093  0.779973  0.290418  4.330881\n",
+       "2           3.005575  3.540363  0.102922  4.849549\n",
+       "3           4.162213  1.061696  0.909125  0.917023\n",
+       "4           1.521211  2.623782  2.159725  1.456146\n",
+       "...              ...       ...       ...       ...\n",
+       "95          0.590824  3.483686  3.144714  4.387360\n",
+       "96          3.675355  4.017405  1.410173  0.887198\n",
+       "97          3.753074  4.034174  4.952526  2.063088\n",
+       "98          1.860090  3.882065  1.704018  4.653787\n",
+       "99          4.292064  2.144970  3.754355  3.772714\n",
+       "\n",
+       "[100 rows x 4 columns]"
+      ]
+     },
+     "execution_count": 4,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# Note the scale of static features.\n",
+    "\n",
+    "from IPython.display import display\n",
+    "\n",
+    "print(\"Min, max values per feature:\")\n",
+    "display(dataset.static.dataframe().describe().T.loc[:, [\"min\", \"max\"]])  # type: ignore\n",
+    "\n",
+    "dataset.static"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Min, max values per feature:\n"
+     ]
+    },
+    {
+     "data": {
+      "text/html": [
+       "<div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th>min</th>\n",
+       "      <th>max</th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th>0</th>\n",
+       "      <td>0.0</td>\n",
+       "      <td>1.0</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>1</th>\n",
+       "      <td>0.0</td>\n",
+       "      <td>1.0</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>2</th>\n",
+       "      <td>0.0</td>\n",
+       "      <td>1.0</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>3</th>\n",
+       "      <td>0.0</td>\n",
+       "      <td>1.0</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "   min  max\n",
+       "0  0.0  1.0\n",
+       "1  0.0  1.0\n",
+       "2  0.0  1.0\n",
+       "3  0.0  1.0"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<p><span style=\"font-family: monospace;\">StaticSamples</span> with data:</p><div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th>0</th>\n",
+       "      <th>1</th>\n",
+       "      <th>2</th>\n",
+       "      <th>3</th>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_idx</th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th>0</th>\n",
+       "      <td>0.385452</td>\n",
+       "      <td>0.959893</td>\n",
+       "      <td>0.733472</td>\n",
+       "      <td>0.609374</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>1</th>\n",
+       "      <td>0.157483</td>\n",
+       "      <td>0.149662</td>\n",
+       "      <td>0.038662</td>\n",
+       "      <td>0.889440</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>2</th>\n",
+       "      <td>0.621823</td>\n",
+       "      <td>0.712515</td>\n",
+       "      <td>0.000000</td>\n",
+       "      <td>0.998040</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>3</th>\n",
+       "      <td>0.863151</td>\n",
+       "      <td>0.207107</td>\n",
+       "      <td>0.166241</td>\n",
+       "      <td>0.174642</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>0.312115</td>\n",
+       "      <td>0.525621</td>\n",
+       "      <td>0.424118</td>\n",
+       "      <td>0.287524</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>...</th>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>95</th>\n",
+       "      <td>0.117993</td>\n",
+       "      <td>0.700959</td>\n",
+       "      <td>0.627225</td>\n",
+       "      <td>0.901266</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>96</th>\n",
+       "      <td>0.761570</td>\n",
+       "      <td>0.809786</td>\n",
+       "      <td>0.269558</td>\n",
+       "      <td>0.168397</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>97</th>\n",
+       "      <td>0.777786</td>\n",
+       "      <td>0.813205</td>\n",
+       "      <td>1.000000</td>\n",
+       "      <td>0.414607</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>98</th>\n",
+       "      <td>0.382821</td>\n",
+       "      <td>0.782190</td>\n",
+       "      <td>0.330150</td>\n",
+       "      <td>0.957051</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>99</th>\n",
+       "      <td>0.890244</td>\n",
+       "      <td>0.427990</td>\n",
+       "      <td>0.752934</td>\n",
+       "      <td>0.772571</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "<p>100 rows × 4 columns</p>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "StaticSamples with data:\n",
+       "                   0         1         2         3\n",
+       "sample_idx                                        \n",
+       "0           0.385452  0.959893  0.733472  0.609374\n",
+       "1           0.157483  0.149662  0.038662  0.889440\n",
+       "2           0.621823  0.712515  0.000000  0.998040\n",
+       "3           0.863151  0.207107  0.166241  0.174642\n",
+       "4           0.312115  0.525621  0.424118  0.287524\n",
+       "...              ...       ...       ...       ...\n",
+       "95          0.117993  0.700959  0.627225  0.901266\n",
+       "96          0.761570  0.809786  0.269558  0.168397\n",
+       "97          0.777786  0.813205  1.000000  0.414607\n",
+       "98          0.382821  0.782190  0.330150  0.957051\n",
+       "99          0.890244  0.427990  0.752934  0.772571\n",
+       "\n",
+       "[100 rows x 4 columns]"
+      ]
+     },
+     "execution_count": 5,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# Note the new scale of static features.\n",
+    "\n",
+    "dataset = model.fit_transform(dataset)  # Or call fit() then transform().\n",
+    "\n",
+    "print(\"Min, max values per feature:\")\n",
+    "display(dataset.static.dataframe().describe().T.loc[:, [\"min\", \"max\"]])  # type: ignore\n",
+    "\n",
+    "dataset.static"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Using a temporal data scaling plugin"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "OneOffPredictionDataset(\n",
+      "    time_series=TimeSeriesSamples([100, *, 5]),\n",
+      "    static=StaticSamples([100, 4]),\n",
+      "    predictive=OneOffPredictionTaskData(targets=StaticSamples([100, 1]))\n",
+      ")\n",
+      "TimeSeriesStandardScaler(\n",
+      "    name='ts_standard_scaler',\n",
+      "    category='preprocessing.scaling.temporal',\n",
+      "    params={}\n",
+      ")\n"
+     ]
+    }
+   ],
+   "source": [
+    "from tempor.utils.dataloaders import SineDataLoader\n",
+    "from tempor.plugins import plugin_loader\n",
+    "\n",
+    "dataset = SineDataLoader(ts_scale=5.0, random_state=42).load()\n",
+    "print(dataset)\n",
+    "\n",
+    "model = plugin_loader.get(\"preprocessing.scaling.temporal.ts_standard_scaler\")\n",
+    "print(model)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Min, max values per feature:\n"
+     ]
+    },
+    {
+     "data": {
+      "text/html": [
+       "<div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th>min</th>\n",
+       "      <th>max</th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th>0</th>\n",
+       "      <td>-4.999519</td>\n",
+       "      <td>4.999999</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>1</th>\n",
+       "      <td>-4.999982</td>\n",
+       "      <td>4.999999</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>2</th>\n",
+       "      <td>-4.999923</td>\n",
+       "      <td>4.999992</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>3</th>\n",
+       "      <td>-4.999979</td>\n",
+       "      <td>5.000000</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>-4.999970</td>\n",
+       "      <td>4.999928</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "        min       max\n",
+       "0 -4.999519  4.999999\n",
+       "1 -4.999982  4.999999\n",
+       "2 -4.999923  4.999992\n",
+       "3 -4.999979  5.000000\n",
+       "4 -4.999970  4.999928"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<p><span style=\"font-family: monospace;\">TimeSeriesSamples</span> with data:</p><div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th>0</th>\n",
+       "      <th>1</th>\n",
+       "      <th>2</th>\n",
+       "      <th>3</th>\n",
+       "      <th>4</th>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_idx</th>\n",
+       "      <th>time_idx</th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"5\" valign=\"top\">0</th>\n",
+       "      <th>0</th>\n",
+       "      <td>-0.095075</td>\n",
+       "      <td>-0.240884</td>\n",
+       "      <td>-0.542729</td>\n",
+       "      <td>2.209324</td>\n",
+       "      <td>0.122539</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>1</th>\n",
+       "      <td>1.500152</td>\n",
+       "      <td>1.822750</td>\n",
+       "      <td>2.882952</td>\n",
+       "      <td>4.450264</td>\n",
+       "      <td>2.673609</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>2</th>\n",
+       "      <td>2.939520</td>\n",
+       "      <td>3.567547</td>\n",
+       "      <td>4.864963</td>\n",
+       "      <td>4.930896</td>\n",
+       "      <td>4.464728</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>3</th>\n",
+       "      <td>4.073484</td>\n",
+       "      <td>4.688307</td>\n",
+       "      <td>4.410788</td>\n",
+       "      <td>3.461105</td>\n",
+       "      <td>4.986786</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>4.784229</td>\n",
+       "      <td>4.988986</td>\n",
+       "      <td>1.747861</td>\n",
+       "      <td>0.622269</td>\n",
+       "      <td>4.091392</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>...</th>\n",
+       "      <th>...</th>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"5\" valign=\"top\">99</th>\n",
+       "      <th>5</th>\n",
+       "      <td>4.835604</td>\n",
+       "      <td>0.634449</td>\n",
+       "      <td>4.634897</td>\n",
+       "      <td>4.910111</td>\n",
+       "      <td>4.815565</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>6</th>\n",
+       "      <td>3.532665</td>\n",
+       "      <td>2.066645</td>\n",
+       "      <td>2.845170</td>\n",
+       "      <td>3.281070</td>\n",
+       "      <td>4.946122</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>7</th>\n",
+       "      <td>1.263739</td>\n",
+       "      <td>3.315606</td>\n",
+       "      <td>0.121903</td>\n",
+       "      <td>0.253339</td>\n",
+       "      <td>4.998853</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>8</th>\n",
+       "      <td>-1.350749</td>\n",
+       "      <td>4.270597</td>\n",
+       "      <td>-2.641363</td>\n",
+       "      <td>-2.882388</td>\n",
+       "      <td>4.972930</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>9</th>\n",
+       "      <td>-3.595883</td>\n",
+       "      <td>4.846944</td>\n",
+       "      <td>-4.537960</td>\n",
+       "      <td>-4.789380</td>\n",
+       "      <td>4.868760</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "<p>1000 rows × 5 columns</p>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "TimeSeriesSamples with data:\n",
+       "                            0         1         2         3         4\n",
+       "sample_idx time_idx                                                  \n",
+       "0          0        -0.095075 -0.240884 -0.542729  2.209324  0.122539\n",
+       "           1         1.500152  1.822750  2.882952  4.450264  2.673609\n",
+       "           2         2.939520  3.567547  4.864963  4.930896  4.464728\n",
+       "           3         4.073484  4.688307  4.410788  3.461105  4.986786\n",
+       "           4         4.784229  4.988986  1.747861  0.622269  4.091392\n",
+       "...                       ...       ...       ...       ...       ...\n",
+       "99         5         4.835604  0.634449  4.634897  4.910111  4.815565\n",
+       "           6         3.532665  2.066645  2.845170  3.281070  4.946122\n",
+       "           7         1.263739  3.315606  0.121903  0.253339  4.998853\n",
+       "           8        -1.350749  4.270597 -2.641363 -2.882388  4.972930\n",
+       "           9        -3.595883  4.846944 -4.537960 -4.789380  4.868760\n",
+       "\n",
+       "[1000 rows x 5 columns]"
+      ]
+     },
+     "execution_count": 7,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# Note the scale of time series features.\n",
+    "\n",
+    "from IPython.display import display\n",
+    "\n",
+    "print(\"Min, max values per feature:\")\n",
+    "display(dataset.time_series.dataframe().describe().T.loc[:, [\"min\", \"max\"]])\n",
+    "\n",
+    "dataset.time_series"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Min, max values per feature:\n"
+     ]
+    },
+    {
+     "data": {
+      "text/html": [
+       "<div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th>min</th>\n",
+       "      <th>max</th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th>0</th>\n",
+       "      <td>-1.711349</td>\n",
+       "      <td>1.200819</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>1</th>\n",
+       "      <td>-1.724449</td>\n",
+       "      <td>1.239101</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>2</th>\n",
+       "      <td>-1.734762</td>\n",
+       "      <td>1.230568</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>3</th>\n",
+       "      <td>-1.592516</td>\n",
+       "      <td>1.277314</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>-1.728804</td>\n",
+       "      <td>1.177170</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "        min       max\n",
+       "0 -1.711349  1.200819\n",
+       "1 -1.724449  1.239101\n",
+       "2 -1.734762  1.230568\n",
+       "3 -1.592516  1.277314\n",
+       "4 -1.728804  1.177170"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<p><span style=\"font-family: monospace;\">TimeSeriesSamples</span> with data:</p><div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th>0</th>\n",
+       "      <th>1</th>\n",
+       "      <th>2</th>\n",
+       "      <th>3</th>\n",
+       "      <th>4</th>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_idx</th>\n",
+       "      <th>time_idx</th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"5\" valign=\"top\">0</th>\n",
+       "      <th>0</th>\n",
+       "      <td>-0.283024</td>\n",
+       "      <td>-0.314064</td>\n",
+       "      <td>-0.413046</td>\n",
+       "      <td>0.476436</td>\n",
+       "      <td>-0.240201</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>1</th>\n",
+       "      <td>0.181555</td>\n",
+       "      <td>0.297505</td>\n",
+       "      <td>0.602791</td>\n",
+       "      <td>1.119549</td>\n",
+       "      <td>0.501140</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>2</th>\n",
+       "      <td>0.600744</td>\n",
+       "      <td>0.814586</td>\n",
+       "      <td>1.190527</td>\n",
+       "      <td>1.257482</td>\n",
+       "      <td>1.021640</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>3</th>\n",
+       "      <td>0.930989</td>\n",
+       "      <td>1.146729</td>\n",
+       "      <td>1.055848</td>\n",
+       "      <td>0.835676</td>\n",
+       "      <td>1.173350</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>1.137980</td>\n",
+       "      <td>1.235837</td>\n",
+       "      <td>0.266196</td>\n",
+       "      <td>0.020977</td>\n",
+       "      <td>0.913149</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>...</th>\n",
+       "      <th>...</th>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"5\" valign=\"top\">99</th>\n",
+       "      <th>5</th>\n",
+       "      <td>1.152942</td>\n",
+       "      <td>-0.054654</td>\n",
+       "      <td>1.122305</td>\n",
+       "      <td>1.251517</td>\n",
+       "      <td>1.123594</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>6</th>\n",
+       "      <td>0.773486</td>\n",
+       "      <td>0.369785</td>\n",
+       "      <td>0.591587</td>\n",
+       "      <td>0.784009</td>\n",
+       "      <td>1.161533</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>7</th>\n",
+       "      <td>0.112705</td>\n",
+       "      <td>0.739922</td>\n",
+       "      <td>-0.215959</td>\n",
+       "      <td>-0.084900</td>\n",
+       "      <td>1.176857</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>8</th>\n",
+       "      <td>-0.648715</td>\n",
+       "      <td>1.022938</td>\n",
+       "      <td>-1.035365</td>\n",
+       "      <td>-0.984802</td>\n",
+       "      <td>1.169324</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>9</th>\n",
+       "      <td>-1.302567</td>\n",
+       "      <td>1.193742</td>\n",
+       "      <td>-1.597773</td>\n",
+       "      <td>-1.532077</td>\n",
+       "      <td>1.139052</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "<p>1000 rows × 5 columns</p>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "TimeSeriesSamples with data:\n",
+       "                            0         1         2         3         4\n",
+       "sample_idx time_idx                                                  \n",
+       "0          0        -0.283024 -0.314064 -0.413046  0.476436 -0.240201\n",
+       "           1         0.181555  0.297505  0.602791  1.119549  0.501140\n",
+       "           2         0.600744  0.814586  1.190527  1.257482  1.021640\n",
+       "           3         0.930989  1.146729  1.055848  0.835676  1.173350\n",
+       "           4         1.137980  1.235837  0.266196  0.020977  0.913149\n",
+       "...                       ...       ...       ...       ...       ...\n",
+       "99         5         1.152942 -0.054654  1.122305  1.251517  1.123594\n",
+       "           6         0.773486  0.369785  0.591587  0.784009  1.161533\n",
+       "           7         0.112705  0.739922 -0.215959 -0.084900  1.176857\n",
+       "           8        -0.648715  1.022938 -1.035365 -0.984802  1.169324\n",
+       "           9        -1.302567  1.193742 -1.597773 -1.532077  1.139052\n",
+       "\n",
+       "[1000 rows x 5 columns]"
+      ]
+     },
+     "execution_count": 8,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# Note the new scale of time series features.\n",
+    "\n",
+    "dataset = model.fit_transform(dataset)  # Or call fit() then transform().\n",
+    "\n",
+    "print(\"Min, max values per feature:\")\n",
+    "display(dataset.time_series.dataframe().describe().T.loc[:, [\"min\", \"max\"]])\n",
+    "\n",
+    "dataset.time_series"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## 🎉 Congratulations!\n",
+    "\n",
+    "Congratulations on completing this notebook tutorial! If you enjoyed this and would like to join the movement towards *Machine learning and AI for Medicine*, you can do so in the following ways!\n",
+    "\n",
+    "\n",
+    "\n",
+    "### ⭐ Star [TemporAI](https://github.com/vanderschaarlab/temporai) on GitHub\n",
+    "\n",
+    "- The easiest way to help our community is by just starring the repos! This helps raise awareness of the tools we're building.\n",
+    "\n",
+    "\n",
+    "\n",
+    "### Check out other projects from [vanderschaarlab](https://github.com/vanderschaarlab)\n",
+    "- 📝 [HyperImpute](https://github.com/vanderschaarlab/hyperimpute)\n",
+    "- 📊 [AutoPrognosis](https://github.com/vanderschaarlab/autoprognosis)\n",
+    "- 🤖 [SynthCity](https://github.com/vanderschaarlab/synthcity)\n",
+    " "
+   ]
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "RE_py38_temporai",
+   "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.15"
+  },
+  "orig_nbformat": 4
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/tutorials/user_guide/tutorial04_prediction.ipynb b/tutorials/user_guide/tutorial04_prediction.ipynb
new file mode 100644
index 00000000..fda30202
--- /dev/null
+++ b/tutorials/user_guide/tutorial04_prediction.ipynb
@@ -0,0 +1,835 @@
+{
+ "cells": [
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# User Guide Tutorial 04: Prediction\n",
+    "\n",
+    "This tutorial shows how to use TemporAI `prediction` plugins."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "*Skip the below cell if you are not on Google Colab / already have TemporAI installed:*"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "%pip install temporai\n",
+    "\n",
+    "# Or from the repo, for the latest version:\n",
+    "# %pip install git+https://github.com/vanderschaarlab/temporai.git"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## All `prediction` plugins\n",
+    "\n",
+    "To see all the relevant plugins:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\">{</span>\n",
+       "    <span style=\"color: #008000; text-decoration-color: #008000\">'one_off'</span>: <span style=\"font-weight: bold\">{</span>\n",
+       "        <span style=\"color: #008000; text-decoration-color: #008000\">'classification'</span>: <span style=\"font-weight: bold\">[</span><span style=\"color: #008000; text-decoration-color: #008000\">'cde_classifier'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'ode_classifier'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'nn_classifier'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'laplace_ode_classifier'</span><span style=\"font-weight: bold\">]</span>,\n",
+       "        <span style=\"color: #008000; text-decoration-color: #008000\">'regression'</span>: <span style=\"font-weight: bold\">[</span><span style=\"color: #008000; text-decoration-color: #008000\">'laplace_ode_regressor'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'nn_regressor'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'ode_regressor'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'cde_regressor'</span><span style=\"font-weight: bold\">]</span>\n",
+       "    <span style=\"font-weight: bold\">}</span>,\n",
+       "    <span style=\"color: #008000; text-decoration-color: #008000\">'temporal'</span>: <span style=\"font-weight: bold\">{</span><span style=\"color: #008000; text-decoration-color: #008000\">'classification'</span>: <span style=\"font-weight: bold\">[</span><span style=\"color: #008000; text-decoration-color: #008000\">'seq2seq_classifier'</span><span style=\"font-weight: bold\">]</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'regression'</span>: <span style=\"font-weight: bold\">[</span><span style=\"color: #008000; text-decoration-color: #008000\">'seq2seq_regressor'</span><span style=\"font-weight: bold\">]}</span>\n",
+       "<span style=\"font-weight: bold\">}</span>\n",
+       "</pre>\n"
+      ],
+      "text/plain": [
+       "\u001b[1m{\u001b[0m\n",
+       "    \u001b[32m'one_off'\u001b[0m: \u001b[1m{\u001b[0m\n",
+       "        \u001b[32m'classification'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'cde_classifier'\u001b[0m, \u001b[32m'ode_classifier'\u001b[0m, \u001b[32m'nn_classifier'\u001b[0m, \u001b[32m'laplace_ode_classifier'\u001b[0m\u001b[1m]\u001b[0m,\n",
+       "        \u001b[32m'regression'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'laplace_ode_regressor'\u001b[0m, \u001b[32m'nn_regressor'\u001b[0m, \u001b[32m'ode_regressor'\u001b[0m, \u001b[32m'cde_regressor'\u001b[0m\u001b[1m]\u001b[0m\n",
+       "    \u001b[1m}\u001b[0m,\n",
+       "    \u001b[32m'temporal'\u001b[0m: \u001b[1m{\u001b[0m\u001b[32m'classification'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'seq2seq_classifier'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'regression'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'seq2seq_regressor'\u001b[0m\u001b[1m]\u001b[0m\u001b[1m}\u001b[0m\n",
+       "\u001b[1m}\u001b[0m\n"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "from tempor.plugins import plugin_loader\n",
+    "from rich.pretty import pprint\n",
+    "\n",
+    "all_prediction_plugins = plugin_loader.list()[\"prediction\"]\n",
+    "\n",
+    "pprint(all_prediction_plugins, indent_guides=False)"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Using a one-off prediction plugin\n",
+    "\n",
+    "One-off prediction is the task of predicting a single value for each sample (may be classification or regression)."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "OneOffPredictionDataset(\n",
+      "    time_series=TimeSeriesSamples([100, *, 5]),\n",
+      "    static=StaticSamples([100, 4]),\n",
+      "    predictive=OneOffPredictionTaskData(targets=StaticSamples([100, 1]))\n",
+      ")\n",
+      "NeuralNetClassifier(\n",
+      "    name='nn_classifier',\n",
+      "    category='prediction.one_off.classification',\n",
+      "    params={\n",
+      "        'n_static_units_hidden': 100,\n",
+      "        'n_static_layers_hidden': 2,\n",
+      "        'n_temporal_units_hidden': 102,\n",
+      "        'n_temporal_layers_hidden': 2,\n",
+      "        'n_iter': 50,\n",
+      "        'mode': 'RNN',\n",
+      "        'n_iter_print': 10,\n",
+      "        'batch_size': 100,\n",
+      "        'lr': 0.001,\n",
+      "        'weight_decay': 0.001,\n",
+      "        'window_size': 1,\n",
+      "        'device': None,\n",
+      "        'dataloader_sampler': None,\n",
+      "        'dropout': 0.0,\n",
+      "        'nonlin': 'relu',\n",
+      "        'random_state': 0,\n",
+      "        'clipping_value': 1,\n",
+      "        'patience': 20,\n",
+      "        'train_ratio': 0.8\n",
+      "    }\n",
+      ")\n"
+     ]
+    }
+   ],
+   "source": [
+    "from tempor.utils.dataloaders import SineDataLoader\n",
+    "from tempor.plugins import plugin_loader\n",
+    "\n",
+    "dataset = SineDataLoader(random_state=42).load()\n",
+    "print(dataset)\n",
+    "\n",
+    "model = plugin_loader.get(\"prediction.one_off.classification.nn_classifier\", n_iter=50)\n",
+    "print(model)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<p><span style=\"font-family: monospace;\">StaticSamples</span> with data:</p><div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th>0</th>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_idx</th>\n",
+       "      <th></th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th>0</th>\n",
+       "      <td>0</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>1</th>\n",
+       "      <td>1</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>2</th>\n",
+       "      <td>0</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>3</th>\n",
+       "      <td>0</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>1</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>...</th>\n",
+       "      <td>...</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>95</th>\n",
+       "      <td>1</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>96</th>\n",
+       "      <td>1</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>97</th>\n",
+       "      <td>1</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>98</th>\n",
+       "      <td>0</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>99</th>\n",
+       "      <td>0</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "<p>100 rows × 1 columns</p>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "StaticSamples with data:\n",
+       "            0\n",
+       "sample_idx   \n",
+       "0           0\n",
+       "1           1\n",
+       "2           0\n",
+       "3           0\n",
+       "4           1\n",
+       "...        ..\n",
+       "95          1\n",
+       "96          1\n",
+       "97          1\n",
+       "98          0\n",
+       "99          0\n",
+       "\n",
+       "[100 rows x 1 columns]"
+      ]
+     },
+     "execution_count": 4,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# Targets:\n",
+    "dataset.predictive.targets"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "NeuralNetClassifier(\n",
+       "    name='nn_classifier',\n",
+       "    category='prediction.one_off.classification',\n",
+       "    params={\n",
+       "        'n_static_units_hidden': 100,\n",
+       "        'n_static_layers_hidden': 2,\n",
+       "        'n_temporal_units_hidden': 102,\n",
+       "        'n_temporal_layers_hidden': 2,\n",
+       "        'n_iter': 50,\n",
+       "        'mode': 'RNN',\n",
+       "        'n_iter_print': 10,\n",
+       "        'batch_size': 100,\n",
+       "        'lr': 0.001,\n",
+       "        'weight_decay': 0.001,\n",
+       "        'window_size': 1,\n",
+       "        'device': None,\n",
+       "        'dataloader_sampler': None,\n",
+       "        'dropout': 0.0,\n",
+       "        'nonlin': 'relu',\n",
+       "        'random_state': 0,\n",
+       "        'clipping_value': 1,\n",
+       "        'patience': 20,\n",
+       "        'train_ratio': 0.8\n",
+       "    }\n",
+       ")"
+      ]
+     },
+     "execution_count": 5,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# Train.\n",
+    "model.fit(dataset)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<p><span style=\"font-family: monospace;\">StaticSamples</span> with data:</p><div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th>feat_0</th>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_idx</th>\n",
+       "      <th></th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th>0</th>\n",
+       "      <td>0.0</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>1</th>\n",
+       "      <td>1.0</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>2</th>\n",
+       "      <td>1.0</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>3</th>\n",
+       "      <td>0.0</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>0.0</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>...</th>\n",
+       "      <td>...</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>95</th>\n",
+       "      <td>1.0</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>96</th>\n",
+       "      <td>0.0</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>97</th>\n",
+       "      <td>1.0</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>98</th>\n",
+       "      <td>0.0</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>99</th>\n",
+       "      <td>1.0</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "<p>100 rows × 1 columns</p>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "StaticSamples with data:\n",
+       "            feat_0\n",
+       "sample_idx        \n",
+       "0              0.0\n",
+       "1              1.0\n",
+       "2              1.0\n",
+       "3              0.0\n",
+       "4              0.0\n",
+       "...            ...\n",
+       "95             1.0\n",
+       "96             0.0\n",
+       "97             1.0\n",
+       "98             0.0\n",
+       "99             1.0\n",
+       "\n",
+       "[100 rows x 1 columns]"
+      ]
+     },
+     "execution_count": 6,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# Predict:\n",
+    "\n",
+    "model.predict(dataset)"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Using a temporal prediction plugin\n",
+    "\n",
+    "Temporal prediction is the task of predicting a time series for each sample (may be classification or regression)."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "TemporalPredictionDataset(\n",
+      "    time_series=TimeSeriesSamples([100, *, 5]),\n",
+      "    static=StaticSamples([100, 3]),\n",
+      "    predictive=TemporalPredictionTaskData(\n",
+      "        targets=TimeSeriesSamples([100, *, 2])\n",
+      "    )\n",
+      ")\n",
+      "Seq2seqRegressor(\n",
+      "    name='seq2seq_regressor',\n",
+      "    category='prediction.temporal.regression',\n",
+      "    params={\n",
+      "        'encoder_rnn_type': 'LSTM',\n",
+      "        'encoder_hidden_size': 100,\n",
+      "        'encoder_num_layers': 1,\n",
+      "        'encoder_bias': True,\n",
+      "        'encoder_dropout': 0.0,\n",
+      "        'encoder_bidirectional': False,\n",
+      "        'encoder_nonlinearity': None,\n",
+      "        'encoder_proj_size': None,\n",
+      "        'decoder_rnn_type': 'LSTM',\n",
+      "        'decoder_hidden_size': 100,\n",
+      "        'decoder_num_layers': 1,\n",
+      "        'decoder_bias': True,\n",
+      "        'decoder_dropout': 0.0,\n",
+      "        'decoder_bidirectional': False,\n",
+      "        'decoder_nonlinearity': None,\n",
+      "        'decoder_proj_size': None,\n",
+      "        'adapter_hidden_dims': [50],\n",
+      "        'adapter_out_activation': 'Tanh',\n",
+      "        'predictor_hidden_dims': [],\n",
+      "        'predictor_out_activation': None,\n",
+      "        'max_len': None,\n",
+      "        'optimizer_str': 'Adam',\n",
+      "        'optimizer_kwargs': {'lr': 0.01, 'weight_decay': 1e-05},\n",
+      "        'batch_size': 32,\n",
+      "        'epochs': 10,\n",
+      "        'padding_indicator': -999.0\n",
+      "    }\n",
+      ")\n"
+     ]
+    }
+   ],
+   "source": [
+    "from tempor.utils.dataloaders import DummyTemporalPredictionDataLoader\n",
+    "from tempor.plugins import plugin_loader\n",
+    "\n",
+    "dataset = DummyTemporalPredictionDataLoader(random_state=42, temporal_covariates_missing_prob=0.0).load()\n",
+    "print(dataset)\n",
+    "\n",
+    "model = plugin_loader.get(\"prediction.temporal.regression.seq2seq_regressor\", epochs=10)\n",
+    "print(model)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<p><span style=\"font-family: monospace;\">TimeSeriesSamples</span> with data:</p><div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th>0</th>\n",
+       "      <th>1</th>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_idx</th>\n",
+       "      <th>time_idx</th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"5\" valign=\"top\">0</th>\n",
+       "      <th>0</th>\n",
+       "      <td>-3.110475</td>\n",
+       "      <td>-3.566948</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>1</th>\n",
+       "      <td>1.528495</td>\n",
+       "      <td>-0.653673</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>2</th>\n",
+       "      <td>2.275307</td>\n",
+       "      <td>-0.695371</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>3</th>\n",
+       "      <td>4.844060</td>\n",
+       "      <td>3.469371</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>4.420301</td>\n",
+       "      <td>5.147500</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>...</th>\n",
+       "      <th>...</th>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"5\" valign=\"top\">99</th>\n",
+       "      <th>7</th>\n",
+       "      <td>5.994185</td>\n",
+       "      <td>6.225290</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>8</th>\n",
+       "      <td>10.913662</td>\n",
+       "      <td>5.346697</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>9</th>\n",
+       "      <td>9.558824</td>\n",
+       "      <td>7.585175</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>10</th>\n",
+       "      <td>10.194430</td>\n",
+       "      <td>5.795619</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>11</th>\n",
+       "      <td>13.774189</td>\n",
+       "      <td>8.457336</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "<p>1573 rows × 2 columns</p>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "TimeSeriesSamples with data:\n",
+       "                             0         1\n",
+       "sample_idx time_idx                     \n",
+       "0          0         -3.110475 -3.566948\n",
+       "           1          1.528495 -0.653673\n",
+       "           2          2.275307 -0.695371\n",
+       "           3          4.844060  3.469371\n",
+       "           4          4.420301  5.147500\n",
+       "...                        ...       ...\n",
+       "99         7          5.994185  6.225290\n",
+       "           8         10.913662  5.346697\n",
+       "           9          9.558824  7.585175\n",
+       "           10        10.194430  5.795619\n",
+       "           11        13.774189  8.457336\n",
+       "\n",
+       "[1573 rows x 2 columns]"
+      ]
+     },
+     "execution_count": 8,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# Targets:\n",
+    "dataset.predictive.targets"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Preparing data for decoder training...\n",
+      "Preparing data for decoder training DONE.\n",
+      "=== Training stage: 1. Train encoder ===\n",
+      "Epoch: 0, Loss: 68.64124755859375\n",
+      "Epoch: 1, Loss: 35.37634651184082\n",
+      "Epoch: 2, Loss: 21.269977149963378\n",
+      "Epoch: 3, Loss: 17.418054847717286\n",
+      "Epoch: 4, Loss: 13.851956520080567\n",
+      "Epoch: 5, Loss: 8.335217247009277\n",
+      "Epoch: 6, Loss: 6.385376853942871\n",
+      "Epoch: 7, Loss: 5.112505340576172\n",
+      "Epoch: 8, Loss: 4.690582332611084\n",
+      "Epoch: 9, Loss: 4.158801422119141\n",
+      "=== Training stage: 2. Train decoder ===\n",
+      "Epoch: 0, Loss: 29.110631188485222\n",
+      "Epoch: 1, Loss: 4.417614046603097\n",
+      "Epoch: 2, Loss: 3.908697671333463\n",
+      "Epoch: 3, Loss: 3.8485680392058788\n",
+      "Epoch: 4, Loss: 3.8276885692068126\n",
+      "Epoch: 5, Loss: 3.793576312405029\n",
+      "Epoch: 6, Loss: 3.749186389072364\n",
+      "Epoch: 7, Loss: 3.787092407949102\n",
+      "Epoch: 8, Loss: 3.7378030509586164\n",
+      "Epoch: 9, Loss: 3.717736062595655\n"
+     ]
+    }
+   ],
+   "source": [
+    "# Train.\n",
+    "model.fit(dataset);"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<p><span style=\"font-family: monospace;\">TimeSeriesSamples</span> with data:</p><div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th>0</th>\n",
+       "      <th>1</th>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_idx</th>\n",
+       "      <th>time_idx</th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"5\" valign=\"top\">0</th>\n",
+       "      <th>11</th>\n",
+       "      <td>9.828533</td>\n",
+       "      <td>8.405809</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>12</th>\n",
+       "      <td>9.831676</td>\n",
+       "      <td>8.414574</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>13</th>\n",
+       "      <td>9.813161</td>\n",
+       "      <td>8.395016</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>14</th>\n",
+       "      <td>9.798813</td>\n",
+       "      <td>8.378744</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>15</th>\n",
+       "      <td>9.772892</td>\n",
+       "      <td>8.352385</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>...</th>\n",
+       "      <th>...</th>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"5\" valign=\"top\">99</th>\n",
+       "      <th>17</th>\n",
+       "      <td>11.214181</td>\n",
+       "      <td>9.754721</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>18</th>\n",
+       "      <td>11.275115</td>\n",
+       "      <td>9.821613</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>19</th>\n",
+       "      <td>11.298031</td>\n",
+       "      <td>9.848743</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>20</th>\n",
+       "      <td>11.280746</td>\n",
+       "      <td>9.832634</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>21</th>\n",
+       "      <td>11.256371</td>\n",
+       "      <td>9.801851</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "<p>1000 rows × 2 columns</p>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "TimeSeriesSamples with data:\n",
+       "                             0         1\n",
+       "sample_idx time_idx                     \n",
+       "0          11         9.828533  8.405809\n",
+       "           12         9.831676  8.414574\n",
+       "           13         9.813161  8.395016\n",
+       "           14         9.798813  8.378744\n",
+       "           15         9.772892  8.352385\n",
+       "...                        ...       ...\n",
+       "99         17        11.214181  9.754721\n",
+       "           18        11.275115  9.821613\n",
+       "           19        11.298031  9.848743\n",
+       "           20        11.280746  9.832634\n",
+       "           21        11.256371  9.801851\n",
+       "\n",
+       "[1000 rows x 2 columns]"
+      ]
+     },
+     "execution_count": 10,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# Predict:\n",
+    "\n",
+    "model.predict(dataset, n_future_steps=10)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## 🎉 Congratulations!\n",
+    "\n",
+    "Congratulations on completing this notebook tutorial! If you enjoyed this and would like to join the movement towards *Machine learning and AI for Medicine*, you can do so in the following ways!\n",
+    "\n",
+    "\n",
+    "\n",
+    "### ⭐ Star [TemporAI](https://github.com/vanderschaarlab/temporai) on GitHub\n",
+    "\n",
+    "- The easiest way to help our community is by just starring the repos! This helps raise awareness of the tools we're building.\n",
+    "\n",
+    "\n",
+    "\n",
+    "### Check out other projects from [vanderschaarlab](https://github.com/vanderschaarlab)\n",
+    "- 📝 [HyperImpute](https://github.com/vanderschaarlab/hyperimpute)\n",
+    "- 📊 [AutoPrognosis](https://github.com/vanderschaarlab/autoprognosis)\n",
+    "- 🤖 [SynthCity](https://github.com/vanderschaarlab/synthcity)\n",
+    " "
+   ]
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "RE_py38_temporai",
+   "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.15"
+  },
+  "orig_nbformat": 4
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/tutorials/user_guide/tutorial05_time_to_event.ipynb b/tutorials/user_guide/tutorial05_time_to_event.ipynb
new file mode 100644
index 00000000..604c5257
--- /dev/null
+++ b/tutorials/user_guide/tutorial05_time_to_event.ipynb
@@ -0,0 +1,443 @@
+{
+ "cells": [
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# User Guide Tutorial 05: Time-to-event Analysis\n",
+    "\n",
+    "This tutorial shows how to use TemporAI `time_to_event` plugins."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "*Skip the below cell if you are not on Google Colab / already have TemporAI installed:*"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "%pip install temporai\n",
+    "\n",
+    "# Or from the repo, for the latest version:\n",
+    "# %pip install git+https://github.com/vanderschaarlab/temporai.git"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## All `time_to_event` plugins\n",
+    "\n",
+    "Time-to-event analysis, in the context of TemporAI, refers to models that estimate risk over time for each sample.\n",
+    "This may also be referred to as survival analysis.\n",
+    "\n",
+    "To see all the relevant plugins:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['ts_coxph', 'ts_xgb', 'dynamic_deephit']"
+      ]
+     },
+     "execution_count": 2,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "from tempor.plugins import plugin_loader\n",
+    "\n",
+    "plugin_loader.list()[\"time_to_event\"]"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Using a time-to-event analysis plugin."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "TimeToEventAnalysisDataset(\n",
+      "    time_series=TimeSeriesSamples([312, *, 14]),\n",
+      "    static=StaticSamples([312, 1]),\n",
+      "    predictive=TimeToEventAnalysisTaskData(targets=EventSamples([312, 1]))\n",
+      ")\n",
+      "DynamicDeepHitTimeToEventAnalysis(\n",
+      "    name='dynamic_deephit',\n",
+      "    category='time_to_event',\n",
+      "    params={\n",
+      "        'n_iter': 50,\n",
+      "        'batch_size': 100,\n",
+      "        'lr': 0.001,\n",
+      "        'n_layers_hidden': 1,\n",
+      "        'n_units_hidden': 40,\n",
+      "        'split': 100,\n",
+      "        'rnn_mode': 'GRU',\n",
+      "        'alpha': 0.34,\n",
+      "        'beta': 0.27,\n",
+      "        'sigma': 0.21,\n",
+      "        'dropout': 0.06,\n",
+      "        'device': 'cpu',\n",
+      "        'patience': 20,\n",
+      "        'output_mode': 'MLP',\n",
+      "        'random_state': 0\n",
+      "    }\n",
+      ")\n"
+     ]
+    }
+   ],
+   "source": [
+    "from tempor.utils.dataloaders import PBCDataLoader\n",
+    "from tempor.plugins import plugin_loader\n",
+    "\n",
+    "dataset = PBCDataLoader(random_state=42).load()\n",
+    "print(dataset)\n",
+    "\n",
+    "model = plugin_loader.get(\"time_to_event.dynamic_deephit\", n_iter=50)\n",
+    "print(model)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<p><span style=\"font-family: monospace;\">EventSamples</span> with data:</p><div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th>status</th>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_idx</th>\n",
+       "      <th></th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th>1</th>\n",
+       "      <td>(0.569488555470374, True)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>2</th>\n",
+       "      <td>(14.1523381885883, False)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>3</th>\n",
+       "      <td>(0.7365020260650499, True)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>(0.27653050049282957, True)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>5</th>\n",
+       "      <td>(4.12057824991786, False)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>...</th>\n",
+       "      <td>...</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>308</th>\n",
+       "      <td>(4.98850071186069, False)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>309</th>\n",
+       "      <td>(4.55317051801555, False)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>310</th>\n",
+       "      <td>(4.4025846019056, False)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>311</th>\n",
+       "      <td>(4.12879202716022, False)</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>312</th>\n",
+       "      <td>(3.98915781404008, False)</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "<p>312 rows × 1 columns</p>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "EventSamples with data:\n",
+       "                                 status\n",
+       "sample_idx                             \n",
+       "1             (0.569488555470374, True)\n",
+       "2             (14.1523381885883, False)\n",
+       "3            (0.7365020260650499, True)\n",
+       "4           (0.27653050049282957, True)\n",
+       "5             (4.12057824991786, False)\n",
+       "...                                 ...\n",
+       "308           (4.98850071186069, False)\n",
+       "309           (4.55317051801555, False)\n",
+       "310            (4.4025846019056, False)\n",
+       "311           (4.12879202716022, False)\n",
+       "312           (3.98915781404008, False)\n",
+       "\n",
+       "[312 rows x 1 columns]"
+      ]
+     },
+     "execution_count": 4,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# Targets:\n",
+    "dataset.predictive.targets"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "DynamicDeepHitTimeToEventAnalysis(\n",
+       "    name='dynamic_deephit',\n",
+       "    category='time_to_event',\n",
+       "    params={\n",
+       "        'n_iter': 50,\n",
+       "        'batch_size': 100,\n",
+       "        'lr': 0.001,\n",
+       "        'n_layers_hidden': 1,\n",
+       "        'n_units_hidden': 40,\n",
+       "        'split': 100,\n",
+       "        'rnn_mode': 'GRU',\n",
+       "        'alpha': 0.34,\n",
+       "        'beta': 0.27,\n",
+       "        'sigma': 0.21,\n",
+       "        'dropout': 0.06,\n",
+       "        'device': 'cpu',\n",
+       "        'patience': 20,\n",
+       "        'output_mode': 'MLP',\n",
+       "        'random_state': 0\n",
+       "    }\n",
+       ")"
+      ]
+     },
+     "execution_count": 5,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# Train.\n",
+    "model.fit(dataset)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<p><span style=\"font-family: monospace;\">TimeSeriesSamples</span> with data:</p><div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th>risk_score</th>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_idx</th>\n",
+       "      <th>time_idx</th>\n",
+       "      <th></th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"3\" valign=\"top\">1</th>\n",
+       "      <th>0.25</th>\n",
+       "      <td>0.422643</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>0.50</th>\n",
+       "      <td>0.626620</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>0.75</th>\n",
+       "      <td>0.717206</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"2\" valign=\"top\">2</th>\n",
+       "      <th>0.25</th>\n",
+       "      <td>0.221314</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>0.50</th>\n",
+       "      <td>0.288492</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>...</th>\n",
+       "      <th>...</th>\n",
+       "      <td>...</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"2\" valign=\"top\">311</th>\n",
+       "      <th>0.50</th>\n",
+       "      <td>0.039302</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>0.75</th>\n",
+       "      <td>0.048346</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"3\" valign=\"top\">312</th>\n",
+       "      <th>0.25</th>\n",
+       "      <td>0.248833</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>0.50</th>\n",
+       "      <td>0.390042</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>0.75</th>\n",
+       "      <td>0.444533</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "<p>936 rows × 1 columns</p>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "TimeSeriesSamples with data:\n",
+       "                     risk_score\n",
+       "sample_idx time_idx            \n",
+       "1          0.25        0.422643\n",
+       "           0.50        0.626620\n",
+       "           0.75        0.717206\n",
+       "2          0.25        0.221314\n",
+       "           0.50        0.288492\n",
+       "...                         ...\n",
+       "311        0.50        0.039302\n",
+       "           0.75        0.048346\n",
+       "312        0.25        0.248833\n",
+       "           0.50        0.390042\n",
+       "           0.75        0.444533\n",
+       "\n",
+       "[936 rows x 1 columns]"
+      ]
+     },
+     "execution_count": 12,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# Predict:\n",
+    "\n",
+    "model.predict(dataset, horizons=[0.25, 0.50, 0.75])"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## 🎉 Congratulations!\n",
+    "\n",
+    "Congratulations on completing this notebook tutorial! If you enjoyed this and would like to join the movement towards *Machine learning and AI for Medicine*, you can do so in the following ways!\n",
+    "\n",
+    "\n",
+    "\n",
+    "### ⭐ Star [TemporAI](https://github.com/vanderschaarlab/temporai) on GitHub\n",
+    "\n",
+    "- The easiest way to help our community is by just starring the repos! This helps raise awareness of the tools we're building.\n",
+    "\n",
+    "\n",
+    "\n",
+    "### Check out other projects from [vanderschaarlab](https://github.com/vanderschaarlab)\n",
+    "- 📝 [HyperImpute](https://github.com/vanderschaarlab/hyperimpute)\n",
+    "- 📊 [AutoPrognosis](https://github.com/vanderschaarlab/autoprognosis)\n",
+    "- 🤖 [SynthCity](https://github.com/vanderschaarlab/synthcity)\n",
+    " "
+   ]
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "RE_py38_temporai",
+   "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.15"
+  },
+  "orig_nbformat": 4
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/tutorials/user_guide/tutorial06_treatments.ipynb b/tutorials/user_guide/tutorial06_treatments.ipynb
new file mode 100644
index 00000000..9f72ce72
--- /dev/null
+++ b/tutorials/user_guide/tutorial06_treatments.ipynb
@@ -0,0 +1,577 @@
+{
+ "cells": [
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# User Guide Tutorial 06: Treatment Effects\n",
+    "\n",
+    "This tutorial shows how to use TemporAI `treatments` plugins."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "*Skip the below cell if you are not on Google Colab / already have TemporAI installed:*"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "%pip install temporai\n",
+    "\n",
+    "# Or from the repo, for the latest version:\n",
+    "# %pip install git+https://github.com/vanderschaarlab/temporai.git"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## All `treatments` plugins\n",
+    "\n",
+    "> ⚠️ The `treatments` API is preliminary and likely to change.\n",
+    "\n",
+    "In the treatment effects estimation task, the goal is to predict a counterfactual outcome given an alternative treatment.\n",
+    "\n",
+    "To see all the relevant plugins:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\">{</span>\n",
+       "    <span style=\"color: #008000; text-decoration-color: #008000\">'one_off'</span>: <span style=\"font-weight: bold\">{</span><span style=\"color: #008000; text-decoration-color: #008000\">'regression'</span>: <span style=\"font-weight: bold\">[</span><span style=\"color: #008000; text-decoration-color: #008000\">'synctwin_regressor'</span><span style=\"font-weight: bold\">]}</span>,\n",
+       "    <span style=\"color: #008000; text-decoration-color: #008000\">'temporal'</span>: <span style=\"font-weight: bold\">{</span><span style=\"color: #008000; text-decoration-color: #008000\">'classification'</span>: <span style=\"font-weight: bold\">[</span><span style=\"color: #008000; text-decoration-color: #008000\">'crn_classifier'</span><span style=\"font-weight: bold\">]</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'regression'</span>: <span style=\"font-weight: bold\">[</span><span style=\"color: #008000; text-decoration-color: #008000\">'crn_regressor'</span><span style=\"font-weight: bold\">]}</span>\n",
+       "<span style=\"font-weight: bold\">}</span>\n",
+       "</pre>\n"
+      ],
+      "text/plain": [
+       "\u001b[1m{\u001b[0m\n",
+       "    \u001b[32m'one_off'\u001b[0m: \u001b[1m{\u001b[0m\u001b[32m'regression'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'synctwin_regressor'\u001b[0m\u001b[1m]\u001b[0m\u001b[1m}\u001b[0m,\n",
+       "    \u001b[32m'temporal'\u001b[0m: \u001b[1m{\u001b[0m\u001b[32m'classification'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'crn_classifier'\u001b[0m\u001b[1m]\u001b[0m, \u001b[32m'regression'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'crn_regressor'\u001b[0m\u001b[1m]\u001b[0m\u001b[1m}\u001b[0m\n",
+       "\u001b[1m}\u001b[0m\n"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "from tempor.plugins import plugin_loader\n",
+    "from rich.pretty import pprint\n",
+    "\n",
+    "all_treatments_plugins = plugin_loader.list()[\"treatments\"]\n",
+    "\n",
+    "pprint(all_treatments_plugins, indent_guides=False)"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Using a temporal treatment effects plugin.\n",
+    "\n",
+    "In this setting, the treatments are time series, and the outcomes are also time series."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "TemporalTreatmentEffectsDataset(\n",
+      "    time_series=TimeSeriesSamples([100, *, 5]),\n",
+      "    static=StaticSamples([100, 3]),\n",
+      "    predictive=TemporalTreatmentEffectsTaskData(\n",
+      "        targets=TimeSeriesSamples([100, *, 2]),\n",
+      "        treatments=TimeSeriesSamples([100, *, 1])\n",
+      "    )\n",
+      ")\n",
+      "CRNTreatmentsRegressor(\n",
+      "    name='crn_regressor',\n",
+      "    category='treatments.temporal.regression',\n",
+      "    params={\n",
+      "        'encoder_rnn_type': 'LSTM',\n",
+      "        'encoder_hidden_size': 100,\n",
+      "        'encoder_num_layers': 1,\n",
+      "        'encoder_bias': True,\n",
+      "        'encoder_dropout': 0.0,\n",
+      "        'encoder_bidirectional': False,\n",
+      "        'encoder_nonlinearity': None,\n",
+      "        'encoder_proj_size': None,\n",
+      "        'decoder_rnn_type': 'LSTM',\n",
+      "        'decoder_hidden_size': 100,\n",
+      "        'decoder_num_layers': 1,\n",
+      "        'decoder_bias': True,\n",
+      "        'decoder_dropout': 0.0,\n",
+      "        'decoder_bidirectional': False,\n",
+      "        'decoder_nonlinearity': None,\n",
+      "        'decoder_proj_size': None,\n",
+      "        'adapter_hidden_dims': [50],\n",
+      "        'adapter_out_activation': 'Tanh',\n",
+      "        'predictor_hidden_dims': [],\n",
+      "        'predictor_out_activation': None,\n",
+      "        'max_len': None,\n",
+      "        'optimizer_str': 'Adam',\n",
+      "        'optimizer_kwargs': {'lr': 0.01, 'weight_decay': 1e-05},\n",
+      "        'batch_size': 32,\n",
+      "        'epochs': 20,\n",
+      "        'padding_indicator': -999.0\n",
+      "    }\n",
+      ")\n"
+     ]
+    }
+   ],
+   "source": [
+    "from tempor.utils.dataloaders import DummyTemporalTreatmentEffectsDataLoader\n",
+    "from tempor.plugins import plugin_loader\n",
+    "\n",
+    "dataset = DummyTemporalTreatmentEffectsDataLoader(\n",
+    "    random_state=42,\n",
+    "    temporal_covariates_missing_prob=0.0,\n",
+    "    temporal_treatments_n_features=1,\n",
+    "    temporal_treatments_n_categories=2,\n",
+    ").load()\n",
+    "print(dataset)\n",
+    "\n",
+    "model = plugin_loader.get(\"treatments.temporal.regression.crn_regressor\", epochs=20)\n",
+    "print(model)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<p><span style=\"font-family: monospace;\">TimeSeriesSamples</span> with data:</p><div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th>0</th>\n",
+       "      <th>1</th>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_idx</th>\n",
+       "      <th>time_idx</th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"5\" valign=\"top\">0</th>\n",
+       "      <th>0</th>\n",
+       "      <td>-3.110475</td>\n",
+       "      <td>-3.566948</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>1</th>\n",
+       "      <td>1.528495</td>\n",
+       "      <td>-0.653673</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>2</th>\n",
+       "      <td>2.275307</td>\n",
+       "      <td>-0.695371</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>3</th>\n",
+       "      <td>4.844060</td>\n",
+       "      <td>3.469371</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>4.420301</td>\n",
+       "      <td>5.147500</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>...</th>\n",
+       "      <th>...</th>\n",
+       "      <td>...</td>\n",
+       "      <td>...</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"5\" valign=\"top\">99</th>\n",
+       "      <th>7</th>\n",
+       "      <td>5.994185</td>\n",
+       "      <td>6.225290</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>8</th>\n",
+       "      <td>10.913662</td>\n",
+       "      <td>5.346697</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>9</th>\n",
+       "      <td>9.558824</td>\n",
+       "      <td>7.585175</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>10</th>\n",
+       "      <td>10.194430</td>\n",
+       "      <td>5.795619</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>11</th>\n",
+       "      <td>13.774189</td>\n",
+       "      <td>8.457336</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "<p>1573 rows × 2 columns</p>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "TimeSeriesSamples with data:\n",
+       "                             0         1\n",
+       "sample_idx time_idx                     \n",
+       "0          0         -3.110475 -3.566948\n",
+       "           1          1.528495 -0.653673\n",
+       "           2          2.275307 -0.695371\n",
+       "           3          4.844060  3.469371\n",
+       "           4          4.420301  5.147500\n",
+       "...                        ...       ...\n",
+       "99         7          5.994185  6.225290\n",
+       "           8         10.913662  5.346697\n",
+       "           9          9.558824  7.585175\n",
+       "           10        10.194430  5.795619\n",
+       "           11        13.774189  8.457336\n",
+       "\n",
+       "[1573 rows x 2 columns]"
+      ]
+     },
+     "execution_count": 4,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# Targets:\n",
+    "dataset.predictive.targets"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<p><span style=\"font-family: monospace;\">TimeSeriesSamples</span> with data:</p><div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th>0</th>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_idx</th>\n",
+       "      <th>time_idx</th>\n",
+       "      <th></th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"5\" valign=\"top\">0</th>\n",
+       "      <th>0</th>\n",
+       "      <td>0</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>1</th>\n",
+       "      <td>1</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>2</th>\n",
+       "      <td>1</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>3</th>\n",
+       "      <td>0</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>0</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>...</th>\n",
+       "      <th>...</th>\n",
+       "      <td>...</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th rowspan=\"5\" valign=\"top\">99</th>\n",
+       "      <th>7</th>\n",
+       "      <td>1</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>8</th>\n",
+       "      <td>1</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>9</th>\n",
+       "      <td>0</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>10</th>\n",
+       "      <td>0</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>11</th>\n",
+       "      <td>1</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "<p>1573 rows × 1 columns</p>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "TimeSeriesSamples with data:\n",
+       "                     0\n",
+       "sample_idx time_idx   \n",
+       "0          0         0\n",
+       "           1         1\n",
+       "           2         1\n",
+       "           3         0\n",
+       "           4         0\n",
+       "...                 ..\n",
+       "99         7         1\n",
+       "           8         1\n",
+       "           9         0\n",
+       "           10        0\n",
+       "           11        1\n",
+       "\n",
+       "[1573 rows x 1 columns]"
+      ]
+     },
+     "execution_count": 5,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# Treatments:\n",
+    "dataset.predictive.treatments"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Preparing data for decoder training...\n",
+      "Preparing data for decoder training DONE.\n",
+      "=== Training stage: 1. Train encoder ===\n",
+      "Epoch: 0, Prediction Loss: 76.050, Lambda: 1.000, Treatment BR Loss: 0.000, Loss: 76.050\n",
+      "Epoch: 1, Prediction Loss: 37.508, Lambda: 1.000, Treatment BR Loss: 0.000, Loss: 37.508\n",
+      "Epoch: 2, Prediction Loss: 21.953, Lambda: 1.000, Treatment BR Loss: 0.000, Loss: 21.953\n",
+      "Epoch: 3, Prediction Loss: 18.895, Lambda: 1.000, Treatment BR Loss: 0.000, Loss: 18.895\n",
+      "Epoch: 4, Prediction Loss: 19.568, Lambda: 1.000, Treatment BR Loss: 0.000, Loss: 19.568\n",
+      "Epoch: 5, Prediction Loss: 16.534, Lambda: 1.000, Treatment BR Loss: 0.000, Loss: 16.534\n",
+      "Epoch: 6, Prediction Loss: 12.039, Lambda: 1.000, Treatment BR Loss: 0.000, Loss: 12.039\n",
+      "Epoch: 7, Prediction Loss: 10.009, Lambda: 1.000, Treatment BR Loss: 0.000, Loss: 10.009\n",
+      "Epoch: 8, Prediction Loss: 8.666, Lambda: 1.000, Treatment BR Loss: 0.000, Loss: 8.666\n",
+      "Epoch: 9, Prediction Loss: 6.788, Lambda: 1.000, Treatment BR Loss: 0.000, Loss: 6.788\n",
+      "Epoch: 10, Prediction Loss: 5.674, Lambda: 1.000, Treatment BR Loss: 0.000, Loss: 5.674\n",
+      "Epoch: 11, Prediction Loss: 5.016, Lambda: 1.000, Treatment BR Loss: 0.000, Loss: 5.016\n",
+      "Epoch: 12, Prediction Loss: 4.605, Lambda: 1.000, Treatment BR Loss: 0.000, Loss: 4.605\n",
+      "Epoch: 13, Prediction Loss: 4.349, Lambda: 1.000, Treatment BR Loss: 0.000, Loss: 4.349\n",
+      "Epoch: 14, Prediction Loss: 4.096, Lambda: 1.000, Treatment BR Loss: 0.000, Loss: 4.096\n",
+      "Epoch: 15, Prediction Loss: 4.008, Lambda: 1.000, Treatment BR Loss: 0.000, Loss: 4.008\n",
+      "Epoch: 16, Prediction Loss: 4.159, Lambda: 1.000, Treatment BR Loss: 0.000, Loss: 4.159\n",
+      "Epoch: 17, Prediction Loss: 3.980, Lambda: 1.000, Treatment BR Loss: 0.000, Loss: 3.980\n",
+      "Epoch: 18, Prediction Loss: 3.904, Lambda: 1.000, Treatment BR Loss: 0.000, Loss: 3.904\n",
+      "Epoch: 19, Prediction Loss: 3.995, Lambda: 1.000, Treatment BR Loss: 0.000, Loss: 3.995\n",
+      "=== Training stage: 2. Train decoder ===\n",
+      "Epoch: 0, Prediction Loss: 34.805, Lambda: 1.000, Treatment BR Loss: 0.000, Loss: 34.805\n",
+      "Epoch: 1, Prediction Loss: 13.675, Lambda: 1.000, Treatment BR Loss: 0.000, Loss: 13.675\n",
+      "Epoch: 2, Prediction Loss: 7.021, Lambda: 1.000, Treatment BR Loss: 0.000, Loss: 7.021\n",
+      "Epoch: 3, Prediction Loss: 4.086, Lambda: 1.000, Treatment BR Loss: 0.000, Loss: 4.086\n",
+      "Epoch: 4, Prediction Loss: 3.847, Lambda: 1.000, Treatment BR Loss: 0.000, Loss: 3.847\n",
+      "Epoch: 5, Prediction Loss: 3.795, Lambda: 1.000, Treatment BR Loss: 0.000, Loss: 3.795\n",
+      "Epoch: 6, Prediction Loss: 3.762, Lambda: 1.000, Treatment BR Loss: 0.000, Loss: 3.762\n",
+      "Epoch: 7, Prediction Loss: 3.800, Lambda: 1.000, Treatment BR Loss: 0.000, Loss: 3.800\n",
+      "Epoch: 8, Prediction Loss: 3.792, Lambda: 1.000, Treatment BR Loss: 0.000, Loss: 3.792\n",
+      "Epoch: 9, Prediction Loss: 3.703, Lambda: 1.000, Treatment BR Loss: 0.000, Loss: 3.703\n",
+      "Epoch: 10, Prediction Loss: 3.683, Lambda: 1.000, Treatment BR Loss: 0.000, Loss: 3.683\n",
+      "Epoch: 11, Prediction Loss: 3.734, Lambda: 1.000, Treatment BR Loss: 0.000, Loss: 3.734\n",
+      "Epoch: 12, Prediction Loss: 3.690, Lambda: 1.000, Treatment BR Loss: 0.000, Loss: 3.690\n",
+      "Epoch: 13, Prediction Loss: 3.728, Lambda: 1.000, Treatment BR Loss: 0.000, Loss: 3.728\n",
+      "Epoch: 14, Prediction Loss: 3.694, Lambda: 1.000, Treatment BR Loss: 0.000, Loss: 3.694\n",
+      "Epoch: 15, Prediction Loss: 3.647, Lambda: 1.000, Treatment BR Loss: 0.000, Loss: 3.647\n",
+      "Epoch: 16, Prediction Loss: 3.639, Lambda: 1.000, Treatment BR Loss: 0.000, Loss: 3.639\n",
+      "Epoch: 17, Prediction Loss: 3.612, Lambda: 1.000, Treatment BR Loss: 0.000, Loss: 3.612\n",
+      "Epoch: 18, Prediction Loss: 3.633, Lambda: 1.000, Treatment BR Loss: 0.000, Loss: 3.633\n",
+      "Epoch: 19, Prediction Loss: 3.604, Lambda: 1.000, Treatment BR Loss: 0.000, Loss: 3.604\n"
+     ]
+    }
+   ],
+   "source": [
+    "# Train.\n",
+    "model.fit(dataset);"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Horizons for sample 0:\n",
+      " [5, 6, 7, 8, 9, 10]\n",
+      "\n",
+      "Alternative treatment scenarios for sample 0:\n",
+      " [array([1, 1, 1, 1, 1, 1]), array([0, 0, 0, 0, 0, 0])]\n",
+      "\n",
+      "Counterfactual outcomes for sample 0, given the alternative treatment scenarios:\n",
+      "\n",
+      "Treatment scenario 0, [1 1 1 1 1 1]\n",
+      "TimeSeries() with data:\n",
+      "                 0         1\n",
+      "time_idx                    \n",
+      "5         6.339921  5.118720\n",
+      "6         6.379971  5.159422\n",
+      "7         6.380514  5.159956\n",
+      "8         6.380521  5.159964\n",
+      "9         6.380521  5.159964\n",
+      "10        6.380521  5.159964\n",
+      "\n",
+      "Treatment scenario 1, [0 0 0 0 0 0]\n",
+      "TimeSeries() with data:\n",
+      "                 0         1\n",
+      "time_idx                    \n",
+      "5         6.694273  5.142348\n",
+      "6         6.732183  5.177425\n",
+      "7         6.732780  5.178019\n",
+      "8         6.732789  5.178029\n",
+      "9         6.732790  5.178029\n",
+      "10        6.732790  5.178029\n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "# Predict counterfactuals:\n",
+    "\n",
+    "import numpy as np\n",
+    "\n",
+    "dataset = dataset[:5]\n",
+    "\n",
+    "# Define horizons for each sample.\n",
+    "horizons = [tc.time_indexes()[0][len(tc.time_indexes()[0]) // 2 :] for tc in dataset.time_series]\n",
+    "print(\"Horizons for sample 0:\\n\", horizons[0], end=\"\\n\\n\")\n",
+    "\n",
+    "# Define treatment scenarios for each sample.\n",
+    "treatment_scenarios = [[np.asarray([1] * len(h)), np.asarray([0] * len(h))] for h in horizons]\n",
+    "print(\"Alternative treatment scenarios for sample 0:\\n\", treatment_scenarios[0], end=\"\\n\\n\")\n",
+    "\n",
+    "# Call predict_counterfactuals.\n",
+    "counterfactuals = model.predict_counterfactuals(dataset, horizons=horizons, treatment_scenarios=treatment_scenarios)\n",
+    "print(\"Counterfactual outcomes for sample 0, given the alternative treatment scenarios:\\n\")\n",
+    "for idx, c in enumerate(counterfactuals[0]):\n",
+    "    print(f\"Treatment scenario {idx}, {treatment_scenarios[0][idx]}\")\n",
+    "    print(c, end=\"\\n\\n\")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## 🎉 Congratulations!\n",
+    "\n",
+    "Congratulations on completing this notebook tutorial! If you enjoyed this and would like to join the movement towards *Machine learning and AI for Medicine*, you can do so in the following ways!\n",
+    "\n",
+    "\n",
+    "\n",
+    "### ⭐ Star [TemporAI](https://github.com/vanderschaarlab/temporai) on GitHub\n",
+    "\n",
+    "- The easiest way to help our community is by just starring the repos! This helps raise awareness of the tools we're building.\n",
+    "\n",
+    "\n",
+    "\n",
+    "### Check out other projects from [vanderschaarlab](https://github.com/vanderschaarlab)\n",
+    "- 📝 [HyperImpute](https://github.com/vanderschaarlab/hyperimpute)\n",
+    "- 📊 [AutoPrognosis](https://github.com/vanderschaarlab/autoprognosis)\n",
+    "- 🤖 [SynthCity](https://github.com/vanderschaarlab/synthcity)\n",
+    " "
+   ]
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "RE_py38_temporai",
+   "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.15"
+  },
+  "orig_nbformat": 4
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/tutorials/user_guide/tutorial07_pipeline.ipynb b/tutorials/user_guide/tutorial07_pipeline.ipynb
new file mode 100644
index 00000000..032a5d7f
--- /dev/null
+++ b/tutorials/user_guide/tutorial07_pipeline.ipynb
@@ -0,0 +1,271 @@
+{
+ "cells": [
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# User Guide Tutorial 07: Pipeline\n",
+    "\n",
+    "This tutorial shows how to use TemporAI `Pipeline`s."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "*Skip the below cell if you are not on Google Colab / already have TemporAI installed:*"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "%pip install temporai\n",
+    "\n",
+    "# Or from the repo, for the latest version:\n",
+    "# %pip install git+https://github.com/vanderschaarlab/temporai.git"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## TemporAI `Pipeline`\n",
+    "\n",
+    "A TemporAI `Pipeline` allows you to combine multiple plugins into one;\n",
+    "inspired by be [scikit-learn pipeline](https://scikit-learn.org/stable/modules/generated/sklearn.pipeline.Pipeline.html).\n",
+    "\n",
+    "* All but the final plugin in the pipeline need to be data transformers (the `preprocessing` plugin category),\n",
+    "* The final one must be a predictive plugin (any of the `prediction`, `time_to_event`, `treatments` plugin categories)."
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Example\n",
+    "\n",
+    "Below is an example of a pipeline ending with `prediction.one_off.nn_classifier`.\n",
+    "\n",
+    "Initializing the `Pipeline`:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Pipeline class: <class 'tempor.plugins.pipeline.bfill_static_imputation_ts_minmax_scaler_nn_classifier'>\n",
+      "Pipeline instance: <tempor.plugins.pipeline.bfill_static_imputation_ts_minmax_scaler_nn_classifier object at 0x7f196514da00>\n"
+     ]
+    }
+   ],
+   "source": [
+    "from tempor.plugins.pipeline import Pipeline\n",
+    "\n",
+    "pipeline_class = Pipeline(\n",
+    "    # Provide plugin names for the pipeline, in order.\n",
+    "    [\n",
+    "        # Preprocessing (data transformer) plugins:\n",
+    "        \"preprocessing.imputation.temporal.bfill\",\n",
+    "        \"preprocessing.imputation.static.static_imputation\",\n",
+    "        \"preprocessing.scaling.temporal.ts_minmax_scaler\",\n",
+    "        # Prediction plugin:\n",
+    "        \"prediction.one_off.classification.nn_classifier\",\n",
+    "    ],\n",
+    ")\n",
+    "print(\"Pipeline class:\", pipeline_class)\n",
+    "\n",
+    "pipeline = pipeline_class(\n",
+    "    # You can provide initialization arguments to each plugin comprising the pipeline as a dictionary, as follows:\n",
+    "    {\n",
+    "        \"static_imputer\": {\"static_imputer\": \"ice\", \"random_state\": 42},\n",
+    "        \"nn_classifier\": {\"n_iter\": 100},\n",
+    "    }\n",
+    ")\n",
+    "print(\"Pipeline instance:\", pipeline)"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Using the `Pipeline`:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<p><span style=\"font-family: monospace;\">StaticSamples</span> with data:</p><div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th>feat_0</th>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_idx</th>\n",
+       "      <th></th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th>0</th>\n",
+       "      <td>1.0</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>1</th>\n",
+       "      <td>1.0</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>2</th>\n",
+       "      <td>1.0</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>3</th>\n",
+       "      <td>1.0</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>4</th>\n",
+       "      <td>0.0</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>...</th>\n",
+       "      <td>...</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>95</th>\n",
+       "      <td>1.0</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>96</th>\n",
+       "      <td>1.0</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>97</th>\n",
+       "      <td>1.0</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>98</th>\n",
+       "      <td>1.0</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>99</th>\n",
+       "      <td>1.0</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "<p>100 rows × 1 columns</p>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "StaticSamples with data:\n",
+       "            feat_0\n",
+       "sample_idx        \n",
+       "0              1.0\n",
+       "1              1.0\n",
+       "2              1.0\n",
+       "3              1.0\n",
+       "4              0.0\n",
+       "...            ...\n",
+       "95             1.0\n",
+       "96             1.0\n",
+       "97             1.0\n",
+       "98             1.0\n",
+       "99             1.0\n",
+       "\n",
+       "[100 rows x 1 columns]"
+      ]
+     },
+     "execution_count": 3,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "from tempor.utils.dataloaders import SineDataLoader\n",
+    "\n",
+    "dataset = SineDataLoader(random_state=42).load()\n",
+    "\n",
+    "# Fit:\n",
+    "pipeline.fit(dataset)\n",
+    "\n",
+    "# Predict:\n",
+    "pipeline.predict(dataset)  # This will transform the data ant then predict."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## 🎉 Congratulations!\n",
+    "\n",
+    "Congratulations on completing this notebook tutorial! If you enjoyed this and would like to join the movement towards *Machine learning and AI for Medicine*, you can do so in the following ways!\n",
+    "\n",
+    "\n",
+    "\n",
+    "### ⭐ Star [TemporAI](https://github.com/vanderschaarlab/temporai) on GitHub\n",
+    "\n",
+    "- The easiest way to help our community is by just starring the repos! This helps raise awareness of the tools we're building.\n",
+    "\n",
+    "\n",
+    "\n",
+    "### Check out other projects from [vanderschaarlab](https://github.com/vanderschaarlab)\n",
+    "- 📝 [HyperImpute](https://github.com/vanderschaarlab/hyperimpute)\n",
+    "- 📊 [AutoPrognosis](https://github.com/vanderschaarlab/autoprognosis)\n",
+    "- 🤖 [SynthCity](https://github.com/vanderschaarlab/synthcity)\n",
+    " "
+   ]
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "RE_py38_temporai",
+   "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.15"
+  },
+  "orig_nbformat": 4
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/tutorials/user_guide/tutorial08_benchmarks.ipynb b/tutorials/user_guide/tutorial08_benchmarks.ipynb
new file mode 100644
index 00000000..59d8cb79
--- /dev/null
+++ b/tutorials/user_guide/tutorial08_benchmarks.ipynb
@@ -0,0 +1,547 @@
+{
+ "cells": [
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# User Guide Tutorial 09: Benchmarks\n",
+    "\n",
+    "TemporAI provides some useful benchmarking tools in `tempor.benchmarks`, these are demonstrated here."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "*Skip the below cell if you are not on Google Colab / already have TemporAI installed:*"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "%pip install temporai\n",
+    "\n",
+    "# Or from the repo, for the latest version:\n",
+    "# %pip install git+https://github.com/vanderschaarlab/temporai.git"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Using `tempor.benchmarks.benchmark_models`\n",
+    "\n",
+    "The `tempor.benchmarks.benchmark_models` function provides a quick way to benchmark a number of models (plugins) for\n",
+    "a particular task.\n",
+    "\n",
+    "It takes a list of models (these may also be a `Pipeline`) and a dataset, and performs cross-validation to\n",
+    "get the mean and standard deviation of the various metrics.\n",
+    "\n",
+    "It returns a tuple `(results_readable, results)` as below."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Results in easily-readable format:\n"
+     ]
+    },
+    {
+     "data": {
+      "text/html": [
+       "<div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th>model_1</th>\n",
+       "      <th>model_2</th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th>aucroc</th>\n",
+       "      <td>0.333 +/- 0.109</td>\n",
+       "      <td>0.422 +/- 0.11</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>aucprc</th>\n",
+       "      <td>0.453 +/- 0.099</td>\n",
+       "      <td>0.456 +/- 0.107</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>accuracy</th>\n",
+       "      <td>0.528 +/- 0.137</td>\n",
+       "      <td>0.519 +/- 0.105</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>f1_score_micro</th>\n",
+       "      <td>0.528 +/- 0.137</td>\n",
+       "      <td>0.519 +/- 0.105</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>f1_score_macro</th>\n",
+       "      <td>0.484 +/- 0.112</td>\n",
+       "      <td>0.338 +/- 0.048</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>f1_score_weighted</th>\n",
+       "      <td>0.514 +/- 0.128</td>\n",
+       "      <td>0.361 +/- 0.116</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>kappa</th>\n",
+       "      <td>0.001 +/- 0.232</td>\n",
+       "      <td>0.0 +/- 0.0</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>kappa_quadratic</th>\n",
+       "      <td>0.001 +/- 0.232</td>\n",
+       "      <td>0.0 +/- 0.0</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>precision_micro</th>\n",
+       "      <td>0.528 +/- 0.137</td>\n",
+       "      <td>0.519 +/- 0.105</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>precision_macro</th>\n",
+       "      <td>0.497 +/- 0.122</td>\n",
+       "      <td>0.259 +/- 0.053</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>precision_weighted</th>\n",
+       "      <td>0.514 +/- 0.128</td>\n",
+       "      <td>0.28 +/- 0.104</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>recall_micro</th>\n",
+       "      <td>0.528 +/- 0.137</td>\n",
+       "      <td>0.519 +/- 0.105</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>recall_macro</th>\n",
+       "      <td>0.486 +/- 0.114</td>\n",
+       "      <td>0.5 +/- 0.0</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>recall_weighted</th>\n",
+       "      <td>0.528 +/- 0.137</td>\n",
+       "      <td>0.519 +/- 0.105</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>mcc</th>\n",
+       "      <td>0.001 +/- 0.235</td>\n",
+       "      <td>0.0 +/- 0.0</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "                            model_1          model_2\n",
+       "aucroc              0.333 +/- 0.109   0.422 +/- 0.11\n",
+       "aucprc              0.453 +/- 0.099  0.456 +/- 0.107\n",
+       "accuracy            0.528 +/- 0.137  0.519 +/- 0.105\n",
+       "f1_score_micro      0.528 +/- 0.137  0.519 +/- 0.105\n",
+       "f1_score_macro      0.484 +/- 0.112  0.338 +/- 0.048\n",
+       "f1_score_weighted   0.514 +/- 0.128  0.361 +/- 0.116\n",
+       "kappa               0.001 +/- 0.232      0.0 +/- 0.0\n",
+       "kappa_quadratic     0.001 +/- 0.232      0.0 +/- 0.0\n",
+       "precision_micro     0.528 +/- 0.137  0.519 +/- 0.105\n",
+       "precision_macro     0.497 +/- 0.122  0.259 +/- 0.053\n",
+       "precision_weighted  0.514 +/- 0.128   0.28 +/- 0.104\n",
+       "recall_micro        0.528 +/- 0.137  0.519 +/- 0.105\n",
+       "recall_macro        0.486 +/- 0.114      0.5 +/- 0.0\n",
+       "recall_weighted     0.528 +/- 0.137  0.519 +/- 0.105\n",
+       "mcc                 0.001 +/- 0.235      0.0 +/- 0.0"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Full results:\n",
+      "\n",
+      "model_1:\n"
+     ]
+    },
+    {
+     "data": {
+      "text/html": [
+       "<div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th>mean</th>\n",
+       "      <th>stddev</th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th>aucroc</th>\n",
+       "      <td>0.333333</td>\n",
+       "      <td>0.108866</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>aucprc</th>\n",
+       "      <td>0.452844</td>\n",
+       "      <td>0.099425</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>accuracy</th>\n",
+       "      <td>0.527778</td>\n",
+       "      <td>0.137493</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>f1_score_micro</th>\n",
+       "      <td>0.527778</td>\n",
+       "      <td>0.137493</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>f1_score_macro</th>\n",
+       "      <td>0.484091</td>\n",
+       "      <td>0.112494</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>f1_score_weighted</th>\n",
+       "      <td>0.514141</td>\n",
+       "      <td>0.127851</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>kappa</th>\n",
+       "      <td>0.001000</td>\n",
+       "      <td>0.232335</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>kappa_quadratic</th>\n",
+       "      <td>0.001000</td>\n",
+       "      <td>0.232335</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>precision_micro</th>\n",
+       "      <td>0.527778</td>\n",
+       "      <td>0.137493</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>precision_macro</th>\n",
+       "      <td>0.497222</td>\n",
+       "      <td>0.121780</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>precision_weighted</th>\n",
+       "      <td>0.513889</td>\n",
+       "      <td>0.127672</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>recall_micro</th>\n",
+       "      <td>0.527778</td>\n",
+       "      <td>0.137493</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>recall_macro</th>\n",
+       "      <td>0.486111</td>\n",
+       "      <td>0.113923</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>recall_weighted</th>\n",
+       "      <td>0.527778</td>\n",
+       "      <td>0.137493</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>mcc</th>\n",
+       "      <td>0.001000</td>\n",
+       "      <td>0.235264</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "                        mean    stddev\n",
+       "aucroc              0.333333  0.108866\n",
+       "aucprc              0.452844  0.099425\n",
+       "accuracy            0.527778  0.137493\n",
+       "f1_score_micro      0.527778  0.137493\n",
+       "f1_score_macro      0.484091  0.112494\n",
+       "f1_score_weighted   0.514141  0.127851\n",
+       "kappa               0.001000  0.232335\n",
+       "kappa_quadratic     0.001000  0.232335\n",
+       "precision_micro     0.527778  0.137493\n",
+       "precision_macro     0.497222  0.121780\n",
+       "precision_weighted  0.513889  0.127672\n",
+       "recall_micro        0.527778  0.137493\n",
+       "recall_macro        0.486111  0.113923\n",
+       "recall_weighted     0.527778  0.137493\n",
+       "mcc                 0.001000  0.235264"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "model_2:\n"
+     ]
+    },
+    {
+     "data": {
+      "text/html": [
+       "<div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th>mean</th>\n",
+       "      <th>stddev</th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th>aucroc</th>\n",
+       "      <td>0.422222</td>\n",
+       "      <td>0.109994</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>aucprc</th>\n",
+       "      <td>0.456349</td>\n",
+       "      <td>0.106738</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>accuracy</th>\n",
+       "      <td>0.518519</td>\n",
+       "      <td>0.105369</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>f1_score_micro</th>\n",
+       "      <td>0.518519</td>\n",
+       "      <td>0.105369</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>f1_score_macro</th>\n",
+       "      <td>0.338162</td>\n",
+       "      <td>0.047609</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>f1_score_weighted</th>\n",
+       "      <td>0.360713</td>\n",
+       "      <td>0.115623</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>kappa</th>\n",
+       "      <td>0.000000</td>\n",
+       "      <td>0.000000</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>kappa_quadratic</th>\n",
+       "      <td>0.000000</td>\n",
+       "      <td>0.000000</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>precision_micro</th>\n",
+       "      <td>0.518519</td>\n",
+       "      <td>0.105369</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>precision_macro</th>\n",
+       "      <td>0.259259</td>\n",
+       "      <td>0.052684</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>precision_weighted</th>\n",
+       "      <td>0.279964</td>\n",
+       "      <td>0.104057</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>recall_micro</th>\n",
+       "      <td>0.518519</td>\n",
+       "      <td>0.105369</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>recall_macro</th>\n",
+       "      <td>0.500000</td>\n",
+       "      <td>0.000000</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>recall_weighted</th>\n",
+       "      <td>0.518519</td>\n",
+       "      <td>0.105369</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>mcc</th>\n",
+       "      <td>0.000000</td>\n",
+       "      <td>0.000000</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "                        mean    stddev\n",
+       "aucroc              0.422222  0.109994\n",
+       "aucprc              0.456349  0.106738\n",
+       "accuracy            0.518519  0.105369\n",
+       "f1_score_micro      0.518519  0.105369\n",
+       "f1_score_macro      0.338162  0.047609\n",
+       "f1_score_weighted   0.360713  0.115623\n",
+       "kappa               0.000000  0.000000\n",
+       "kappa_quadratic     0.000000  0.000000\n",
+       "precision_micro     0.518519  0.105369\n",
+       "precision_macro     0.259259  0.052684\n",
+       "precision_weighted  0.279964  0.104057\n",
+       "recall_micro        0.518519  0.105369\n",
+       "recall_macro        0.500000  0.000000\n",
+       "recall_weighted     0.518519  0.105369\n",
+       "mcc                 0.000000  0.000000"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "from tempor.benchmarks import benchmark_models\n",
+    "from tempor.utils.dataloaders import SineDataLoader\n",
+    "from tempor.plugins import plugin_loader\n",
+    "\n",
+    "from IPython.display import display\n",
+    "\n",
+    "dataset = SineDataLoader(random_state=42, no=25).load()\n",
+    "\n",
+    "results_readable, results = benchmark_models(\n",
+    "    task_type=\"classification\",\n",
+    "    tests=[\n",
+    "        (\"model_1\", plugin_loader.get(\"prediction.one_off.classification.nn_classifier\", n_iter=50)),\n",
+    "        (\"model_2\", plugin_loader.get(\"prediction.one_off.classification.ode_classifier\", n_iter=50)),\n",
+    "    ],\n",
+    "    data=dataset,\n",
+    "    n_splits=3,\n",
+    ")\n",
+    "\n",
+    "print(\"Results in easily-readable format:\")\n",
+    "display(results_readable)\n",
+    "\n",
+    "print(\"Full results:\\n\")\n",
+    "for model, value in results.items():\n",
+    "    print(f\"{model}:\")\n",
+    "    display(value)"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Supported tasks\n",
+    "\n",
+    "> ⚠️ Not all task types are supported by `benchmark_models` yet.\n",
+    "\n",
+    "Supported tasks (for each `task_type` argument):\n",
+    "* `task_type=\"classification\"`: `prediction.one_off.classification` models.\n",
+    "* `task_type=\"regression\"`: `prediction.one_off.regression` models.\n",
+    "* `task_type=\"time_to_event\"`: `time_to_event` models.\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## 🎉 Congratulations!\n",
+    "\n",
+    "Congratulations on completing this notebook tutorial! If you enjoyed this and would like to join the movement towards *Machine learning and AI for Medicine*, you can do so in the following ways!\n",
+    "\n",
+    "\n",
+    "\n",
+    "### ⭐ Star [TemporAI](https://github.com/vanderschaarlab/temporai) on GitHub\n",
+    "\n",
+    "- The easiest way to help our community is by just starring the repos! This helps raise awareness of the tools we're building.\n",
+    "\n",
+    "\n",
+    "\n",
+    "### Check out other projects from [vanderschaarlab](https://github.com/vanderschaarlab)\n",
+    "- 📝 [HyperImpute](https://github.com/vanderschaarlab/hyperimpute)\n",
+    "- 📊 [AutoPrognosis](https://github.com/vanderschaarlab/autoprognosis)\n",
+    "- 🤖 [SynthCity](https://github.com/vanderschaarlab/synthcity)\n",
+    " "
+   ]
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "RE_py38_temporai",
+   "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.15"
+  },
+  "orig_nbformat": 4
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}


Test patch:
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 6a428cc1..ea3533a9 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -1,4 +1,4 @@
-name: Run tests
+name: Tests
 
 on:
   push:
diff --git a/.github/workflows/test_full.yml b/.github/workflows/test_full.yml
index b256c80a..e3d55bc1 100644
--- a/.github/workflows/test_full.yml
+++ b/.github/workflows/test_full.yml
@@ -1,4 +1,4 @@
-name: Run full set of tests (slow)
+name: "Tests: Full"
 
 on:
   schedule:
diff --git a/tests/nb_eval.py b/tests/nb_eval.py
index de030081..385f8a13 100644
--- a/tests/nb_eval.py
+++ b/tests/nb_eval.py
@@ -1,3 +1,4 @@
+import re
 from pathlib import Path
 from time import time
 
@@ -9,11 +10,17 @@
 workspace.mkdir(parents=True, exist_ok=True)
 
 
-def run_notebook(notebook_path: Path) -> None:
+def run_notebook(notebook_path: Path, skip_pip_install: bool = True) -> None:
     with open(notebook_path, encoding="utf8") as f:
-        nb = nbformat.read(f, as_version=4)
+        f_str = f.read()
 
+    if skip_pip_install:
+        # Comment out `pip install` commands, as do not need to run those in test.
+        f_str = re.sub(r"[%!]\s*pip", "#pip", f_str, flags=re.DOTALL)
+
+    nb = nbformat.reads(f_str, as_version=4)
     proc = ExecutePreprocessor(timeout=1800)
+
     # Will raise on cell error:
     proc.preprocess(nb, {"metadata": {"path": workspace}})
 
diff --git a/tests/plugins/core/test_plugins.py b/tests/plugins/core/test_plugins.py
index 7d6c61f6..bf39b71d 100644
--- a/tests/plugins/core/test_plugins.py
+++ b/tests/plugins/core/test_plugins.py
@@ -214,6 +214,16 @@ def test_list_fqns(self, loader):
             "category_b.y.plugin_by2",
         ]
 
+    @pytest.mark.parametrize("loader", [plugin_core.PluginLoader(), plugin_loader])
+    def test_list_categories(self, loader):
+        listed = loader.list_categories()
+
+        assert listed == {
+            "category_a": CategoryAExpectedClass,
+            "category_b.x": CategoryBXExpectedClass,
+            "category_b.y": CategoryBYExpectedClass,
+        }
+
     @pytest.mark.parametrize("loader", [plugin_core.PluginLoader(), plugin_loader])
     def test_get(self, loader):
         plugin_a2_instance = loader.get(  # pylint: disable=unused-variable  # noqa: F841