{ "cells": [ { "cell_type": "markdown", "id": "41296cc6-9d84-47c5-8a92-2d292f6f3c4a", "metadata": { "papermill": { "duration": 0.011815, "end_time": "2026-07-28T16:08:50.744149", "exception": false, "start_time": "2026-07-28T16:08:50.732334", "status": "completed" }, "tags": [] }, "source": [ "# Plots" ] }, { "cell_type": "code", "execution_count": 1, "id": "9286e0b8-3c78-4b0f-943c-d219e9840dfe", "metadata": { "ExecuteTime": { "end_time": "2023-11-22T14:30:12.399978600Z", "start_time": "2023-11-22T14:30:12.220250Z" }, "execution": { "iopub.execute_input": "2026-07-28T16:08:50.760250Z", "iopub.status.busy": "2026-07-28T16:08:50.760065Z", "iopub.status.idle": "2026-07-28T16:08:50.764908Z", "shell.execute_reply": "2026-07-28T16:08:50.764506Z" }, "papermill": { "duration": 0.013964, "end_time": "2026-07-28T16:08:50.766029", "exception": false, "start_time": "2026-07-28T16:08:50.752065", "status": "completed" }, "tags": [] }, "outputs": [], "source": [ "# Import to be able to import python package from src\n", "import sys\n", "sys.path.insert(0, '../src')" ] }, { "cell_type": "code", "execution_count": 2, "id": "2028eed7-b1c3-4c9e-b6a0-00433caa7d0f", "metadata": { "ExecuteTime": { "end_time": "2023-11-22T14:30:12.438915100Z", "start_time": "2023-11-22T14:30:12.223262200Z" }, "execution": { "iopub.execute_input": "2026-07-28T16:08:50.779085Z", "iopub.status.busy": "2026-07-28T16:08:50.778919Z", "iopub.status.idle": "2026-07-28T16:08:56.384940Z", "shell.execute_reply": "2026-07-28T16:08:56.384508Z" }, "papermill": { "duration": 5.614099, "end_time": "2026-07-28T16:08:56.386137", "exception": false, "start_time": "2026-07-28T16:08:50.772038", "status": "completed" }, "tags": [] }, "outputs": [], "source": [ "import pandas as pd\n", "import ontime as on\n", "from darts.datasets import EnergyDataset" ] }, { "cell_type": "markdown", "id": "e24da8ab-6a83-4c2f-9ff0-c633d4693a91", "metadata": { "papermill": { "duration": 0.003958, "end_time": "2026-07-28T16:08:56.394505", "exception": false, "start_time": "2026-07-28T16:08:56.390547", "status": "completed" }, "tags": [] }, "source": [ "## Load data" ] }, { "cell_type": "code", "execution_count": 3, "id": "db08372d-8ab2-4290-9196-76eb0c275629", "metadata": { "ExecuteTime": { "end_time": "2023-11-22T14:30:12.886891300Z", "start_time": "2023-11-22T14:30:12.235870500Z" }, "execution": { "iopub.execute_input": "2026-07-28T16:08:56.403060Z", "iopub.status.busy": "2026-07-28T16:08:56.402866Z", "iopub.status.idle": "2026-07-28T16:08:56.476346Z", "shell.execute_reply": "2026-07-28T16:08:56.475730Z" }, "papermill": { "duration": 0.079084, "end_time": "2026-07-28T16:08:56.477420", "exception": false, "start_time": "2026-07-28T16:08:56.398336", "status": "completed" }, "tags": [] }, "outputs": [], "source": [ "ts = EnergyDataset().load()" ] }, { "cell_type": "markdown", "id": "789865e9-e840-4267-994a-f10743e46279", "metadata": { "papermill": { "duration": 0.00458, "end_time": "2026-07-28T16:08:56.486435", "exception": false, "start_time": "2026-07-28T16:08:56.481855", "status": "completed" }, "tags": [] }, "source": [ "Complete TimeSeries" ] }, { "cell_type": "code", "execution_count": 4, "id": "009bcbe3-b73c-4355-b280-1bcb3d98e113", "metadata": { "ExecuteTime": { "end_time": "2023-11-22T14:30:12.888403100Z", "start_time": "2023-11-22T14:30:12.382164600Z" }, "execution": { "iopub.execute_input": "2026-07-28T16:08:56.495359Z", "iopub.status.busy": "2026-07-28T16:08:56.495211Z", "iopub.status.idle": "2026-07-28T16:08:56.510603Z", "shell.execute_reply": "2026-07-28T16:08:56.510012Z" }, "papermill": { "duration": 0.021034, "end_time": "2026-07-28T16:08:56.511477", "exception": false, "start_time": "2026-07-28T16:08:56.490443", "status": "completed" }, "tags": [] }, "outputs": [], "source": [ "df = ts.to_dataframe()\n", "df = df.interpolate()\n", "cols = ['generation biomass', 'generation solar', 'generation nuclear']\n", "df = df[cols]" ] }, { "cell_type": "code", "execution_count": 5, "id": "7baaa1c5-c460-44bb-a375-f2eff4509cee", "metadata": { "ExecuteTime": { "end_time": "2023-11-22T14:30:12.888403100Z", "start_time": "2023-11-22T14:30:12.406885100Z" }, "execution": { "iopub.execute_input": "2026-07-28T16:08:56.521163Z", "iopub.status.busy": "2026-07-28T16:08:56.521041Z", "iopub.status.idle": "2026-07-28T16:08:56.524894Z", "shell.execute_reply": "2026-07-28T16:08:56.524503Z" }, "papermill": { "duration": 0.009571, "end_time": "2026-07-28T16:08:56.525614", "exception": false, "start_time": "2026-07-28T16:08:56.516043", "status": "completed" }, "tags": [] }, "outputs": [], "source": [ "ts = on.TimeSeries.from_dataframe(df)" ] }, { "cell_type": "markdown", "id": "07386885-6139-43ed-a695-c2fa3cf23904", "metadata": { "papermill": { "duration": 0.00398, "end_time": "2026-07-28T16:08:56.533833", "exception": false, "start_time": "2026-07-28T16:08:56.529853", "status": "completed" }, "tags": [] }, "source": [ "Prepare data" ] }, { "cell_type": "code", "execution_count": 6, "id": "07b54c1f-4215-43c0-8c81-bb337b9f50fb", "metadata": { "ExecuteTime": { "end_time": "2023-11-22T14:30:12.888403100Z", "start_time": "2023-11-22T14:30:12.414642100Z" }, "execution": { "iopub.execute_input": "2026-07-28T16:08:56.542640Z", "iopub.status.busy": "2026-07-28T16:08:56.542534Z", "iopub.status.idle": "2026-07-28T16:08:56.547344Z", "shell.execute_reply": "2026-07-28T16:08:56.546896Z" }, "papermill": { "duration": 0.009902, "end_time": "2026-07-28T16:08:56.547852", "exception": false, "start_time": "2026-07-28T16:08:56.537950", "status": "completed" }, "tags": [] }, "outputs": [], "source": [ "ts_uni = ts['generation solar'].slice(pd.Timestamp('2015'), pd.Timestamp('2016'))\n", "ts_multi = ts.slice(pd.Timestamp('2015'), pd.Timestamp('2016'))" ] }, { "cell_type": "markdown", "id": "a1a7ecfe-894b-42a8-8a94-5163f83b26a4", "metadata": { "papermill": { "duration": 0.004135, "end_time": "2026-07-28T16:08:56.556173", "exception": false, "start_time": "2026-07-28T16:08:56.552038", "status": "completed" }, "tags": [] }, "source": [ "## Primitive Plots" ] }, { "cell_type": "markdown", "id": "a438a78b-3ed5-4501-a316-2414e881dbb3", "metadata": { "papermill": { "duration": 0.005637, "end_time": "2026-07-28T16:08:56.565876", "exception": false, "start_time": "2026-07-28T16:08:56.560239", "status": "completed" }, "tags": [] }, "source": [ "### Line(s)" ] }, { "cell_type": "markdown", "id": "8c60d9ea-e027-4ba0-8fc6-87bfd8059084", "metadata": { "papermill": { "duration": 0.004377, "end_time": "2026-07-28T16:08:56.574490", "exception": false, "start_time": "2026-07-28T16:08:56.570113", "status": "completed" }, "tags": [] }, "source": [ "With univariate TimeSeries" ] }, { "cell_type": "code", "execution_count": 7, "id": "ad694d28-07ff-4563-81a6-84ffe6591b70", "metadata": { "execution": { "iopub.execute_input": "2026-07-28T16:08:56.583540Z", "iopub.status.busy": "2026-07-28T16:08:56.583397Z", "iopub.status.idle": "2026-07-28T16:08:56.923329Z", "shell.execute_reply": "2026-07-28T16:08:56.922575Z" }, "papermill": { "duration": 0.346048, "end_time": "2026-07-28T16:08:56.924607", "exception": false, "start_time": "2026-07-28T16:08:56.578559", "status": "completed" }, "tags": [] }, "outputs": [ { "data": { "text/html": [ "\n", "\n", "
\n", "" ], "text/plain": [ "alt.LayerChart(...)" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "on.Plot(ts_uni.head(400))\\\n", " .add(on.marks.line)\\\n", " .properties(width=600)\\\n", " .show()" ] }, { "cell_type": "markdown", "id": "4de943c7-b0fd-4943-8cb1-8ce496599864", "metadata": { "papermill": { "duration": 0.004651, "end_time": "2026-07-28T16:08:56.934302", "exception": false, "start_time": "2026-07-28T16:08:56.929651", "status": "completed" }, "tags": [] }, "source": [ "with multivariate TimeSeries" ] }, { "cell_type": "code", "execution_count": 8, "id": "2a4a0582-209b-461a-815b-7d4d4698c0f7", "metadata": { "ExecuteTime": { "end_time": "2023-11-22T14:30:12.940457Z", "start_time": "2023-11-22T14:30:12.570624900Z" }, "execution": { "iopub.execute_input": "2026-07-28T16:08:56.944642Z", "iopub.status.busy": "2026-07-28T16:08:56.944490Z", "iopub.status.idle": "2026-07-28T16:08:56.971359Z", "shell.execute_reply": "2026-07-28T16:08:56.970878Z" }, "papermill": { "duration": 0.033194, "end_time": "2026-07-28T16:08:56.972122", "exception": false, "start_time": "2026-07-28T16:08:56.938928", "status": "completed" }, "tags": [] }, "outputs": [ { "data": { "text/html": [ "\n", "\n", "
\n", "" ], "text/plain": [ "alt.LayerChart(...)" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "on.Plot(ts_multi.head(400))\\\n", " .add(on.marks.line)\\\n", " .properties(width=600)\\\n", " .show()" ] }, { "cell_type": "markdown", "id": "2fd66619-22c4-43b5-b827-39b01d16e73b", "metadata": { "papermill": { "duration": 0.004765, "end_time": "2026-07-28T16:08:56.981755", "exception": false, "start_time": "2026-07-28T16:08:56.976990", "status": "completed" }, "tags": [] }, "source": [ "### Dots" ] }, { "cell_type": "markdown", "id": "e1e97a4e-352d-446f-a70f-66c83e6754e1", "metadata": { "papermill": { "duration": 0.004934, "end_time": "2026-07-28T16:08:56.991360", "exception": false, "start_time": "2026-07-28T16:08:56.986426", "status": "completed" }, "tags": [] }, "source": [ "With univariate TimeSeries" ] }, { "cell_type": "code", "execution_count": 9, "id": "f25a59e9-98d3-4519-bc03-feb9f6cd4d2a", "metadata": { "execution": { "iopub.execute_input": "2026-07-28T16:08:57.002030Z", "iopub.status.busy": "2026-07-28T16:08:57.001897Z", "iopub.status.idle": "2026-07-28T16:08:57.027248Z", "shell.execute_reply": "2026-07-28T16:08:57.026786Z" }, "papermill": { "duration": 0.031407, "end_time": "2026-07-28T16:08:57.027838", "exception": false, "start_time": "2026-07-28T16:08:56.996431", "status": "completed" }, "tags": [] }, "outputs": [ { "data": { "text/html": [ "\n", "\n", "
\n", "" ], "text/plain": [ "alt.LayerChart(...)" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "on.Plot(ts_uni.head(400))\\\n", " .add(on.marks.dots)\\\n", " .properties(width=600)\\\n", " .show()" ] }, { "cell_type": "markdown", "id": "8b7e5730-9341-404d-93a9-f6811d2775d9", "metadata": { "papermill": { "duration": 0.005195, "end_time": "2026-07-28T16:08:57.041277", "exception": false, "start_time": "2026-07-28T16:08:57.036082", "status": "completed" }, "tags": [] }, "source": [ "with multivariate TimeSeries" ] }, { "cell_type": "code", "execution_count": 10, "id": "e02804dd-0c24-40e4-9acc-8ed817f03a12", "metadata": { "execution": { "iopub.execute_input": "2026-07-28T16:08:57.051973Z", "iopub.status.busy": "2026-07-28T16:08:57.051866Z", "iopub.status.idle": "2026-07-28T16:08:57.076185Z", "shell.execute_reply": "2026-07-28T16:08:57.075745Z" }, "papermill": { "duration": 0.030702, "end_time": "2026-07-28T16:08:57.076902", "exception": false, "start_time": "2026-07-28T16:08:57.046200", "status": "completed" }, "tags": [] }, "outputs": [ { "data": { "text/html": [ "\n", "\n", "
\n", "" ], "text/plain": [ "alt.LayerChart(...)" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "on.Plot(ts_multi.head(400))\\\n", " .add(on.marks.dots)\\\n", " .properties(width=600)\\\n", " .show()" ] }, { "cell_type": "markdown", "id": "f9b6835a-2bbf-48d6-935d-fa6226cf45c1", "metadata": { "papermill": { "duration": 0.005547, "end_time": "2026-07-28T16:08:57.087994", "exception": false, "start_time": "2026-07-28T16:08:57.082447", "status": "completed" }, "tags": [] }, "source": [ "### Areas" ] }, { "cell_type": "markdown", "id": "8c8f8fc6-ccfd-4c3f-b513-e14842e7849c", "metadata": { "papermill": { "duration": 0.005454, "end_time": "2026-07-28T16:08:57.099074", "exception": false, "start_time": "2026-07-28T16:08:57.093620", "status": "completed" }, "tags": [] }, "source": [ "With a single time series" ] }, { "cell_type": "code", "execution_count": 11, "id": "7db16759-fbf2-46ef-a0da-4eea94f8ca60", "metadata": { "execution": { "iopub.execute_input": "2026-07-28T16:08:57.110739Z", "iopub.status.busy": "2026-07-28T16:08:57.110631Z", "iopub.status.idle": "2026-07-28T16:08:57.175990Z", "shell.execute_reply": "2026-07-28T16:08:57.175499Z" }, "papermill": { "duration": 0.072258, "end_time": "2026-07-28T16:08:57.176603", "exception": false, "start_time": "2026-07-28T16:08:57.104345", "status": "completed" }, "tags": [] }, "outputs": [ { "data": { "text/html": [ "\n", "\n", "
\n", "" ], "text/plain": [ "alt.LayerChart(...)" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "on.Plot(ts_uni.head(400))\\\n", " .add(on.marks.area)\\\n", " .properties(width=600)\\\n", " .show()" ] }, { "cell_type": "markdown", "id": "54c8348a-fafe-49c4-939f-77f1a7a2c9d6", "metadata": { "papermill": { "duration": 0.005506, "end_time": "2026-07-28T16:08:57.188060", "exception": false, "start_time": "2026-07-28T16:08:57.182554", "status": "completed" }, "tags": [] }, "source": [ "With a multivariate time series it works with exactly two" ] }, { "cell_type": "code", "execution_count": 12, "id": "d6b18ef8-7954-4780-8e9a-dd6e8afd6d15", "metadata": { "execution": { "iopub.execute_input": "2026-07-28T16:08:57.199809Z", "iopub.status.busy": "2026-07-28T16:08:57.199694Z", "iopub.status.idle": "2026-07-28T16:08:57.201436Z", "shell.execute_reply": "2026-07-28T16:08:57.201063Z" }, "papermill": { "duration": 0.00854, "end_time": "2026-07-28T16:08:57.202062", "exception": false, "start_time": "2026-07-28T16:08:57.193522", "status": "completed" }, "tags": [] }, "outputs": [], "source": [ "from darts import concatenate" ] }, { "cell_type": "code", "execution_count": 13, "id": "70178386-e035-4c7a-91c2-ee206131635d", "metadata": { "execution": { "iopub.execute_input": "2026-07-28T16:08:57.214406Z", "iopub.status.busy": "2026-07-28T16:08:57.214316Z", "iopub.status.idle": "2026-07-28T16:08:57.218814Z", "shell.execute_reply": "2026-07-28T16:08:57.218487Z" }, "papermill": { "duration": 0.011229, "end_time": "2026-07-28T16:08:57.219390", "exception": false, "start_time": "2026-07-28T16:08:57.208161", "status": "completed" }, "tags": [] }, "outputs": [], "source": [ "# First we create the series with two components\n", "ts_ci = concatenate([\n", " ts_multi.univariate_component(0), \n", " ts_multi.univariate_component(1)\n", "], axis=1)\n", "ts_ci = on.TimeSeries.from_darts(ts_ci)" ] }, { "cell_type": "code", "execution_count": 14, "id": "98ca8c64-bcde-4e93-a0ec-df1410242f36", "metadata": { "execution": { "iopub.execute_input": "2026-07-28T16:08:57.232121Z", "iopub.status.busy": "2026-07-28T16:08:57.232030Z", "iopub.status.idle": "2026-07-28T16:08:57.256155Z", "shell.execute_reply": "2026-07-28T16:08:57.255683Z" }, "papermill": { "duration": 0.031346, "end_time": "2026-07-28T16:08:57.256763", "exception": false, "start_time": "2026-07-28T16:08:57.225417", "status": "completed" }, "tags": [] }, "outputs": [ { "data": { "text/html": [ "\n", "\n", "
\n", "" ], "text/plain": [ "alt.LayerChart(...)" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Then we plot it\n", "on.Plot(ts_ci.head(200))\\\n", " .add(on.marks.area, title='Diff. between solar and biomass generation')\\\n", " .properties(width=600, height=200)\\\n", " .show()" ] }, { "cell_type": "markdown", "id": "f436ba6f-aa4f-47e8-9673-754c9c02e1b4", "metadata": { "papermill": { "duration": 0.005896, "end_time": "2026-07-28T16:08:57.269227", "exception": false, "start_time": "2026-07-28T16:08:57.263331", "status": "completed" }, "tags": [] }, "source": [ "### Heatmaps" ] }, { "attachments": {}, "cell_type": "markdown", "id": "94b74653-0b50-442f-a666-9bd0984f9781", "metadata": { "papermill": { "duration": 0.009231, "end_time": "2026-07-28T16:08:57.284743", "exception": false, "start_time": "2026-07-28T16:08:57.275512", "status": "completed" }, "tags": [] }, "source": [ "with univariate TimeSeries" ] }, { "cell_type": "code", "execution_count": 15, "id": "8a70db18-2736-4b52-8a49-a09908048535", "metadata": { "execution": { "iopub.execute_input": "2026-07-28T16:08:57.297771Z", "iopub.status.busy": "2026-07-28T16:08:57.297675Z", "iopub.status.idle": "2026-07-28T16:08:57.327724Z", "shell.execute_reply": "2026-07-28T16:08:57.327158Z" }, "papermill": { "duration": 0.037268, "end_time": "2026-07-28T16:08:57.328240", "exception": false, "start_time": "2026-07-28T16:08:57.290972", "status": "completed" }, "tags": [] }, "outputs": [ { "data": { "text/html": [ "\n", "\n", "
\n", "" ], "text/plain": [ "alt.LayerChart(...)" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "on.Plot(ts_uni.head(1000))\\\n", " .add(on.marks.heatmap)\\\n", " .properties(width=600, height=50)\\\n", " .show()" ] }, { "cell_type": "markdown", "id": "bb43360b-c5ff-4e95-9af8-7ced3fb66d7d", "metadata": { "papermill": { "duration": 0.006375, "end_time": "2026-07-28T16:08:57.341082", "exception": false, "start_time": "2026-07-28T16:08:57.334707", "status": "completed" }, "tags": [] }, "source": [ "with multivariate Heatmap" ] }, { "cell_type": "code", "execution_count": 16, "id": "95e245b4-d594-45f7-ae7a-04db01fc860d", "metadata": { "ExecuteTime": { "end_time": "2023-11-22T14:30:12.943458900Z", "start_time": "2023-11-22T14:30:12.778200200Z" }, "execution": { "iopub.execute_input": "2026-07-28T16:08:57.354829Z", "iopub.status.busy": "2026-07-28T16:08:57.354692Z", "iopub.status.idle": "2026-07-28T16:08:57.389281Z", "shell.execute_reply": "2026-07-28T16:08:57.388620Z" }, "papermill": { "duration": 0.043536, "end_time": "2026-07-28T16:08:57.390821", "exception": false, "start_time": "2026-07-28T16:08:57.347285", "status": "completed" }, "tags": [] }, "outputs": [ { "data": { "text/html": [ "\n", "\n", "
\n", "" ], "text/plain": [ "alt.LayerChart(...)" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "on.Plot(ts_multi.head(1000))\\\n", " .add(on.marks.heatmap)\\\n", " .properties(width=600, height=150)\\\n", " .show()" ] }, { "cell_type": "markdown", "id": "3b07d001-bef6-4b9b-86b6-105ad318adab", "metadata": { "papermill": { "duration": 0.006714, "end_time": "2026-07-28T16:08:57.405193", "exception": false, "start_time": "2026-07-28T16:08:57.398479", "status": "completed" }, "tags": [] }, "source": [ "---" ] }, { "cell_type": "markdown", "id": "8a52c3c7-3adf-454e-9b6d-b0959adcd8f6", "metadata": { "papermill": { "duration": 0.007285, "end_time": "2026-07-28T16:08:57.419683", "exception": false, "start_time": "2026-07-28T16:08:57.412398", "status": "completed" }, "tags": [] }, "source": [ "## Combined Plots" ] }, { "cell_type": "markdown", "id": "c29b1243-bc85-4a8d-899a-710cbfc2d77b", "metadata": { "papermill": { "duration": 0.006515, "end_time": "2026-07-28T16:08:57.433185", "exception": false, "start_time": "2026-07-28T16:08:57.426670", "status": "completed" }, "tags": [] }, "source": [ "Most of the plots in onTime can be combined as they are based on Altair layered charts. For instance, you can do the following to have a dots on a line." ] }, { "cell_type": "code", "execution_count": 17, "id": "e18041c8-4c74-4f63-be92-56ad1d971bf7", "metadata": { "execution": { "iopub.execute_input": "2026-07-28T16:08:57.447882Z", "iopub.status.busy": "2026-07-28T16:08:57.447729Z", "iopub.status.idle": "2026-07-28T16:08:57.491106Z", "shell.execute_reply": "2026-07-28T16:08:57.490531Z" }, "papermill": { "duration": 0.052103, "end_time": "2026-07-28T16:08:57.491935", "exception": false, "start_time": "2026-07-28T16:08:57.439832", "status": "completed" }, "tags": [] }, "outputs": [ { "data": { "text/html": [ "\n", "\n", "
\n", "" ], "text/plain": [ "alt.LayerChart(...)" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "on.Plot()\\\n", " .add(on.marks.dots, ts_multi.univariate_component(1).head(400))\\\n", " .add(on.marks.line, ts_multi.univariate_component(0).head(400))\\\n", " .properties(width=600, height=200)\\\n", " .show()" ] }, { "cell_type": "markdown", "id": "b7cd4986", "metadata": { "papermill": { "duration": 0.007583, "end_time": "2026-07-28T16:08:57.507060", "exception": false, "start_time": "2026-07-28T16:08:57.499477", "status": "completed" }, "tags": [] }, "source": [ "---" ] }, { "cell_type": "markdown", "id": "f3bec92b", "metadata": { "papermill": { "duration": 0.007232, "end_time": "2026-07-28T16:08:57.521807", "exception": false, "start_time": "2026-07-28T16:08:57.514575", "status": "completed" }, "tags": [] }, "source": [ "## Subplots\n", "\n", "A `Plot` is a single panel. To place several panels in one figure, use the\n", "`on.rows` and `on.cols` factories, which return a `Figure`.\n", "\n", "The names describe the *arguments*, not the container: `on.rows(a, b)` means\n", "\"a and b are rows\", so the panels are stacked vertically. `on.cols(a, b)` places\n", "them side by side. Both accept `Plot` and `Figure` panels, so they nest freely.\n", "\n", "A few rules worth knowing:\n", "\n", "- `share_x` / `share_y` share the scale domain across the panels of a group. They\n", " default to `share_x=True, share_y=False` on `rows` and\n", " `share_x=False, share_y=False` on `cols`.\n", "- **Propagation**: a flag passed explicitly propagates down into nested groups;\n", " a flag left unset lets each nested group use its own default. This is the most\n", " likely source of surprise.\n", "- When the x axis is shared in a vertical stack, the inner x axis labels are hidden\n", " and only drawn on the bottom panel.\n", "- Panel-level `.properties()` wins over figure-level `.properties()`, which only\n", " fills the values a panel left unset.\n", "- `spacing` sets the gap between panels in pixels, and the layout options below\n", " control how much room the axes get.\n", "- `sizes` gives the extent of each child along the stacking axis (heights for `rows`,\n", " widths for `cols`), either as pixels or as fractions summing to 1.0.\n", "\n", "> **Known constraint.** In Vega-Lite 5, `selection_interval(bind=\"scales\")` does not\n", "> reliably propagate across concatenated views, so synchronised pan/zoom across\n", "> panels is not available. Sharing a scale *domain* works, interactive zoom does not." ] }, { "cell_type": "markdown", "id": "73df96b8", "metadata": { "papermill": { "duration": 0.007546, "end_time": "2026-07-28T16:08:57.536584", "exception": false, "start_time": "2026-07-28T16:08:57.529038", "status": "completed" }, "tags": [] }, "source": [ "Let's prepare a few short series to plot." ] }, { "cell_type": "code", "execution_count": 18, "id": "c3e5fbbe", "metadata": { "execution": { "iopub.execute_input": "2026-07-28T16:08:57.552624Z", "iopub.status.busy": "2026-07-28T16:08:57.552453Z", "iopub.status.idle": "2026-07-28T16:08:57.557814Z", "shell.execute_reply": "2026-07-28T16:08:57.557288Z" }, "papermill": { "duration": 0.014056, "end_time": "2026-07-28T16:08:57.558471", "exception": false, "start_time": "2026-07-28T16:08:57.544415", "status": "completed" }, "tags": [] }, "outputs": [], "source": [ "solar = ts_multi['generation solar'].head(400)\n", "nuclear = ts_multi['generation nuclear'].head(400)\n", "biomass = ts_multi['generation biomass'].head(400)\n", "\n", "def line(series, title=None):\n", " plot = on.Plot(series).add(on.marks.line)\n", " return plot.properties(title=title) if title is not None else plot" ] }, { "cell_type": "markdown", "id": "4610e4a2", "metadata": { "papermill": { "duration": 0.007578, "end_time": "2026-07-28T16:08:57.573247", "exception": false, "start_time": "2026-07-28T16:08:57.565669", "status": "completed" }, "tags": [] }, "source": [ "### Stacked signals with a shared time axis\n", "\n", "The x axis is shared, so its labels are only drawn on the bottom panel." ] }, { "cell_type": "code", "execution_count": 19, "id": "0a2b6a9d", "metadata": { "execution": { "iopub.execute_input": "2026-07-28T16:08:57.589037Z", "iopub.status.busy": "2026-07-28T16:08:57.588886Z", "iopub.status.idle": "2026-07-28T16:08:57.654568Z", "shell.execute_reply": "2026-07-28T16:08:57.654177Z" }, "papermill": { "duration": 0.074934, "end_time": "2026-07-28T16:08:57.655534", "exception": false, "start_time": "2026-07-28T16:08:57.580600", "status": "completed" }, "tags": [] }, "outputs": [ { "data": { "text/html": [ "\n", "\n", "
\n", "" ], "text/plain": [ "alt.VConcatChart(...)" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "on.rows(line(solar), line(nuclear), line(biomass))\\\n", " .properties(width=800, height=140)\\\n", " .show()" ] }, { "cell_type": "markdown", "id": "db439728", "metadata": { "papermill": { "duration": 0.007892, "end_time": "2026-07-28T16:08:57.672754", "exception": false, "start_time": "2026-07-28T16:08:57.664862", "status": "completed" }, "tags": [] }, "source": [ "### Unequal heights in pixels\n", "\n", "A tall main panel with a thin heatmap strip below it." ] }, { "cell_type": "code", "execution_count": 20, "id": "fc32c9fb", "metadata": { "execution": { "iopub.execute_input": "2026-07-28T16:08:57.690115Z", "iopub.status.busy": "2026-07-28T16:08:57.689972Z", "iopub.status.idle": "2026-07-28T16:08:57.745615Z", "shell.execute_reply": "2026-07-28T16:08:57.745041Z" }, "papermill": { "duration": 0.06571, "end_time": "2026-07-28T16:08:57.746420", "exception": false, "start_time": "2026-07-28T16:08:57.680710", "status": "completed" }, "tags": [] }, "outputs": [ { "data": { "text/html": [ "\n", "\n", "
\n", "" ], "text/plain": [ "alt.VConcatChart(...)" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "main = on.Plot(solar).add(on.marks.line)\n", "strip = on.Plot(solar).add(on.marks.heatmap)\n", "\n", "on.rows(main, strip, sizes=[240, 40])\\\n", " .properties(width=800)\\\n", " .show()" ] }, { "cell_type": "markdown", "id": "79020ddb", "metadata": { "papermill": { "duration": 0.007847, "end_time": "2026-07-28T16:08:57.763017", "exception": false, "start_time": "2026-07-28T16:08:57.755170", "status": "completed" }, "tags": [] }, "source": [ "### Fractional sizes\n", "\n", "Fractions must sum to 1.0 and are taken along the stacking axis, here the total\n", "height of the figure." ] }, { "cell_type": "code", "execution_count": 21, "id": "adbe6be6", "metadata": { "execution": { "iopub.execute_input": "2026-07-28T16:08:57.780059Z", "iopub.status.busy": "2026-07-28T16:08:57.779925Z", "iopub.status.idle": "2026-07-28T16:08:57.824341Z", "shell.execute_reply": "2026-07-28T16:08:57.823814Z" }, "papermill": { "duration": 0.053912, "end_time": "2026-07-28T16:08:57.825292", "exception": false, "start_time": "2026-07-28T16:08:57.771380", "status": "completed" }, "tags": [] }, "outputs": [ { "data": { "text/html": [ "\n", "\n", "
\n", "" ], "text/plain": [ "alt.VConcatChart(...)" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "forecast = on.Plot(nuclear).add(on.marks.line)\n", "residuals = on.Plot(nuclear.diff()).add(on.marks.line)\n", "\n", "on.rows(forecast, residuals, sizes=[0.72, 0.28])\\\n", " .properties(width=700, height=340)\\\n", " .show()" ] }, { "cell_type": "markdown", "id": "dd73f112", "metadata": { "papermill": { "duration": 0.008897, "end_time": "2026-07-28T16:08:57.843078", "exception": false, "start_time": "2026-07-28T16:08:57.834181", "status": "completed" }, "tags": [] }, "source": [ "### Side by side comparison\n", "\n", "A comparison inverts both defaults: the panels share the y scale so the magnitudes\n", "are comparable, but keep their own x scale because they cover different periods." ] }, { "cell_type": "code", "execution_count": 22, "id": "6eacf032", "metadata": { "execution": { "iopub.execute_input": "2026-07-28T16:08:57.861057Z", "iopub.status.busy": "2026-07-28T16:08:57.860863Z", "iopub.status.idle": "2026-07-28T16:08:57.901785Z", "shell.execute_reply": "2026-07-28T16:08:57.901285Z" }, "papermill": { "duration": 0.051232, "end_time": "2026-07-28T16:08:57.902495", "exception": false, "start_time": "2026-07-28T16:08:57.851263", "status": "completed" }, "tags": [] }, "outputs": [ { "data": { "text/html": [ "\n", "\n", "
\n", "" ], "text/plain": [ "alt.HConcatChart(...)" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ts_2015 = ts['generation solar'].slice(pd.Timestamp('2015-06-01'), pd.Timestamp('2015-06-08'))\n", "ts_2016 = ts['generation solar'].slice(pd.Timestamp('2016-06-01'), pd.Timestamp('2016-06-08'))\n", "\n", "on.cols(line(ts_2015, title='2015'), line(ts_2016, title='2016'), share_y=True, share_x=False)\\\n", " .properties(width=350, height=200)\\\n", " .show()" ] }, { "cell_type": "markdown", "id": "985a8d19", "metadata": { "papermill": { "duration": 0.010427, "end_time": "2026-07-28T16:08:57.921804", "exception": false, "start_time": "2026-07-28T16:08:57.911377", "status": "completed" }, "tags": [] }, "source": [ "### Small multiples\n", "\n", "Groups nest, so a row of columns gives a grid of small multiples." ] }, { "cell_type": "code", "execution_count": 23, "id": "65c23282", "metadata": { "execution": { "iopub.execute_input": "2026-07-28T16:08:57.939125Z", "iopub.status.busy": "2026-07-28T16:08:57.938999Z", "iopub.status.idle": "2026-07-28T16:08:58.001910Z", "shell.execute_reply": "2026-07-28T16:08:58.001279Z" }, "papermill": { "duration": 0.072593, "end_time": "2026-07-28T16:08:58.002734", "exception": false, "start_time": "2026-07-28T16:08:57.930141", "status": "completed" }, "tags": [] }, "outputs": [ { "data": { "text/html": [ "\n", "\n", "
\n", "" ], "text/plain": [ "alt.VConcatChart(...)" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "panels = [line(ts_multi[c].head(400), title=c) for c in ts_multi.components]\n", "\n", "on.rows(on.cols(*panels[:2]), on.cols(*panels[2:]), share_y=True)\\\n", " .properties(width=350, height=140)\\\n", " .show()" ] }, { "cell_type": "markdown", "id": "827b0852", "metadata": { "papermill": { "duration": 0.009456, "end_time": "2026-07-28T16:08:58.023823", "exception": false, "start_time": "2026-07-28T16:08:58.014367", "status": "completed" }, "tags": [] }, "source": [ "### Nesting\n", "\n", "Groups nest freely. Here the inner `rows` inherits nothing from the outer `cols`,\n", "so it uses its own default `share_x=True`, while the outer `cols` keeps\n", "`share_x=False`." ] }, { "cell_type": "code", "execution_count": 24, "id": "f9acbd96", "metadata": { "execution": { "iopub.execute_input": "2026-07-28T16:08:58.046178Z", "iopub.status.busy": "2026-07-28T16:08:58.046029Z", "iopub.status.idle": "2026-07-28T16:08:58.110599Z", "shell.execute_reply": "2026-07-28T16:08:58.110090Z" }, "papermill": { "duration": 0.078401, "end_time": "2026-07-28T16:08:58.111470", "exception": false, "start_time": "2026-07-28T16:08:58.033069", "status": "completed" }, "tags": [] }, "outputs": [ { "data": { "text/html": [ "\n", "\n", "
\n", "" ], "text/plain": [ "alt.HConcatChart(...)" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "profile = on.Plot(biomass).add(on.marks.line)\n", "\n", "on.cols(on.rows(main, strip, sizes=[240, 50]), profile, sizes=[620, 180])\\\n", " .properties(height=290)\\\n", " .show()" ] }, { "cell_type": "markdown", "id": "c9e17aff", "metadata": { "papermill": { "duration": 0.011709, "end_time": "2026-07-28T16:08:58.134022", "exception": false, "start_time": "2026-07-28T16:08:58.122313", "status": "completed" }, "tags": [] }, "source": [ "### Adjusting the layout\n", "\n", "Four options of `Figure.properties()` control how the panels are placed.\n", "\n", "- `spacing` is the gap between panels in pixels (default `4`). The gap is measured\n", " between the *full* bounds of the panels, axes and titles included, so panels never\n", " overrun each other.\n", "- `bounds` selects how a panel is measured: `\"full\"` (default) accounts for the axes\n", " and titles, `\"flush\"` only accounts for the plotting areas. `\"flush\"` packs the\n", " panels tightly but lets axis labels and titles overlap their neighbours, so it is\n", " only useful when the inner axes are hidden.\n", "- `hide_shared_axes` (default `True`) drops the redundant inner axes of a shared\n", " scale: the x axis is kept on the bottom row only, and the y axis on the first\n", " column only. Set it to `False` to draw every axis.\n", "- `axis_extent` (default `40`) is the minimum width reserved for the y axis of every\n", " panel, which keeps the y axis titles aligned across panels. Use `0` to let each\n", " panel size its own axis.\n" ] }, { "cell_type": "code", "execution_count": 25, "id": "e7e10194", "metadata": { "execution": { "iopub.execute_input": "2026-07-28T16:08:58.154717Z", "iopub.status.busy": "2026-07-28T16:08:58.154575Z", "iopub.status.idle": "2026-07-28T16:08:58.212886Z", "shell.execute_reply": "2026-07-28T16:08:58.212446Z" }, "papermill": { "duration": 0.069585, "end_time": "2026-07-28T16:08:58.213672", "exception": false, "start_time": "2026-07-28T16:08:58.144087", "status": "completed" }, "tags": [] }, "outputs": [ { "data": { "text/html": [ "\n", "\n", "
\n", "" ], "text/plain": [ "alt.VConcatChart(...)" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "on.rows(line(solar), line(nuclear), line(biomass))\\\n", " .properties(width=800, height=140, spacing=24, axis_extent=60)\\\n", " .show()" ] }, { "cell_type": "markdown", "id": "69fab142", "metadata": { "papermill": { "duration": 0.012044, "end_time": "2026-07-28T16:08:58.236107", "exception": false, "start_time": "2026-07-28T16:08:58.224063", "status": "completed" }, "tags": [] }, "source": [ "The layout of a figure is available as a symbolic tree, which is handy to check\n", "what was built without touching the data. It reads `/` for a vertical stack, `|`\n", "for a horizontal one, and annotates the panels with their size when they have\n", "one." ] }, { "cell_type": "code", "execution_count": 26, "id": "933cb415", "metadata": { "execution": { "iopub.execute_input": "2026-07-28T16:08:58.259315Z", "iopub.status.busy": "2026-07-28T16:08:58.259164Z", "iopub.status.idle": "2026-07-28T16:08:58.272397Z", "shell.execute_reply": "2026-07-28T16:08:58.272019Z" }, "papermill": { "duration": 0.026601, "end_time": "2026-07-28T16:08:58.272990", "exception": false, "start_time": "2026-07-28T16:08:58.246389", "status": "completed" }, "tags": [] }, "outputs": [ { "data": { "text/plain": [ "solar:0.5 / nuclear:0.5" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "figure = on.rows(line(solar, title='solar'), line(nuclear, title='nuclear'), sizes=[0.5, 0.5])\n", "figure.layout" ] }, { "cell_type": "markdown", "id": "8c1f4d05-d5b2-4d86-8cf0-6165175354eb", "metadata": { "papermill": { "duration": 0.010134, "end_time": "2026-07-28T16:08:58.293081", "exception": false, "start_time": "2026-07-28T16:08:58.282947", "status": "completed" }, "tags": [] }, "source": [ "---" ] }, { "cell_type": "markdown", "id": "e87e999c-4ffa-4f3a-92a8-db894982a2ae", "metadata": { "papermill": { "duration": 0.009864, "end_time": "2026-07-28T16:08:58.312763", "exception": false, "start_time": "2026-07-28T16:08:58.302899", "status": "completed" }, "tags": [] }, "source": [ "## Thematic Plots" ] }, { "cell_type": "markdown", "id": "b65f9e0b-381a-4085-b919-3074b9b18b0a", "metadata": { "papermill": { "duration": 0.011273, "end_time": "2026-07-28T16:08:58.333877", "exception": false, "start_time": "2026-07-28T16:08:58.322604", "status": "completed" }, "tags": [] }, "source": [ "### Forecasts" ] }, { "cell_type": "code", "execution_count": 27, "id": "79328857-d576-43d4-a54a-29196312448b", "metadata": { "execution": { "iopub.execute_input": "2026-07-28T16:08:58.354495Z", "iopub.status.busy": "2026-07-28T16:08:58.354349Z", "iopub.status.idle": "2026-07-28T16:08:58.357325Z", "shell.execute_reply": "2026-07-28T16:08:58.356784Z" }, "papermill": { "duration": 0.014024, "end_time": "2026-07-28T16:08:58.357792", "exception": false, "start_time": "2026-07-28T16:08:58.343768", "status": "completed" }, "tags": [] }, "outputs": [], "source": [ "ts_train, ts_test = ts_uni.split_before(0.9)" ] }, { "cell_type": "code", "execution_count": 28, "id": "53bdff9e-f198-4a24-9968-95c3efaf5ebb", "metadata": { "execution": { "iopub.execute_input": "2026-07-28T16:08:58.380362Z", "iopub.status.busy": "2026-07-28T16:08:58.380231Z", "iopub.status.idle": "2026-07-28T16:08:58.381967Z", "shell.execute_reply": "2026-07-28T16:08:58.381601Z" }, "papermill": { "duration": 0.013351, "end_time": "2026-07-28T16:08:58.382622", "exception": false, "start_time": "2026-07-28T16:08:58.369271", "status": "completed" }, "tags": [] }, "outputs": [], "source": [ "from ontime.context import common" ] }, { "cell_type": "code", "execution_count": 29, "id": "c592bccc-95bf-4b2d-9952-f1b4075288da", "metadata": { "execution": { "iopub.execute_input": "2026-07-28T16:08:58.403375Z", "iopub.status.busy": "2026-07-28T16:08:58.403266Z", "iopub.status.idle": "2026-07-28T16:08:59.561603Z", "shell.execute_reply": "2026-07-28T16:08:59.561172Z" }, "papermill": { "duration": 1.170042, "end_time": "2026-07-28T16:08:59.562401", "exception": false, "start_time": "2026-07-28T16:08:58.392359", "status": "completed" }, "tags": [] }, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 29, "metadata": {}, "output_type": "execute_result" } ], "source": [ "model = common.GenericPredictor()\n", "model.fit(ts_train)" ] }, { "cell_type": "code", "execution_count": 30, "id": "7a92c059-8854-4d26-a51e-5c44cb7fa1e1", "metadata": { "execution": { "iopub.execute_input": "2026-07-28T16:08:59.583739Z", "iopub.status.busy": "2026-07-28T16:08:59.583561Z", "iopub.status.idle": "2026-07-28T16:08:59.600319Z", "shell.execute_reply": "2026-07-28T16:08:59.599832Z" }, "papermill": { "duration": 0.028671, "end_time": "2026-07-28T16:08:59.601374", "exception": false, "start_time": "2026-07-28T16:08:59.572703", "status": "completed" }, "tags": [] }, "outputs": [], "source": [ "ts_pred = model.predict(24 * 3)" ] }, { "cell_type": "code", "execution_count": 31, "id": "609375fd-e994-4336-b1e8-07ea11b38d49", "metadata": { "execution": { "iopub.execute_input": "2026-07-28T16:08:59.623057Z", "iopub.status.busy": "2026-07-28T16:08:59.622895Z", "iopub.status.idle": "2026-07-28T16:08:59.627894Z", "shell.execute_reply": "2026-07-28T16:08:59.627359Z" }, "papermill": { "duration": 0.016707, "end_time": "2026-07-28T16:08:59.628483", "exception": false, "start_time": "2026-07-28T16:08:59.611776", "status": "completed" }, "tags": [] }, "outputs": [], "source": [ "ts_train = ts_train.rename({'generation solar':'Training set'})\n", "ts_test = ts_test.rename({'generation solar':'Test set'})\n", "ts_pred = ts_pred.rename({'generation solar':'Forecast'})" ] }, { "cell_type": "markdown", "id": "2f6c72b8-2124-452f-9577-f4d4ece10803", "metadata": { "papermill": { "duration": 0.010098, "end_time": "2026-07-28T16:08:59.649263", "exception": false, "start_time": "2026-07-28T16:08:59.639165", "status": "completed" }, "tags": [] }, "source": [ "Plot a prediction" ] }, { "cell_type": "code", "execution_count": 32, "id": "99165fdc-d0a5-49d5-a882-adb8b8534e54", "metadata": { "execution": { "iopub.execute_input": "2026-07-28T16:08:59.670327Z", "iopub.status.busy": "2026-07-28T16:08:59.670187Z", "iopub.status.idle": "2026-07-28T16:08:59.714827Z", "shell.execute_reply": "2026-07-28T16:08:59.714238Z" }, "papermill": { "duration": 0.056078, "end_time": "2026-07-28T16:08:59.715460", "exception": false, "start_time": "2026-07-28T16:08:59.659382", "status": "completed" }, "tags": [] }, "outputs": [ { "data": { "text/html": [ "\n", "\n", "
\n", "" ], "text/plain": [ "alt.LayerChart(...)" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(\n", "on.Plot()\n", " .add(on.marks.line, ts_test.head(24 * 3), type='dashed')\n", " .add(on.marks.line, ts_train.tail(24 * 4))\n", " .add(on.marks.line, ts_pred)\n", " .properties(width=600, height=200)\n", " .show()\n", ")" ] }, { "cell_type": "markdown", "id": "8b2d1199-7a74-4586-a834-67fc367229e4", "metadata": { "papermill": { "duration": 0.010409, "end_time": "2026-07-28T16:08:59.736592", "exception": false, "start_time": "2026-07-28T16:08:59.726183", "status": "completed" }, "tags": [] }, "source": [ "### Anomalies" ] }, { "cell_type": "markdown", "id": "9424f948-96fe-4a51-987a-9c323c1af142", "metadata": { "papermill": { "duration": 0.010363, "end_time": "2026-07-28T16:08:59.756950", "exception": false, "start_time": "2026-07-28T16:08:59.746587", "status": "completed" }, "tags": [] }, "source": [ "Create the mock data" ] }, { "cell_type": "code", "execution_count": 33, "id": "0bea5b4f-e11b-4836-a039-d61117a4684d", "metadata": { "execution": { "iopub.execute_input": "2026-07-28T16:08:59.777735Z", "iopub.status.busy": "2026-07-28T16:08:59.777582Z", "iopub.status.idle": "2026-07-28T16:08:59.779580Z", "shell.execute_reply": "2026-07-28T16:08:59.779240Z" }, "papermill": { "duration": 0.013106, "end_time": "2026-07-28T16:08:59.780303", "exception": false, "start_time": "2026-07-28T16:08:59.767197", "status": "completed" }, "tags": [] }, "outputs": [], "source": [ "td_point = on.detectors.quantile(high_quantile=0.99)\n", "td_collective = on.detectors.threshold(low_threshold=-30)\n", "td_contextual = on.detectors.quantile(high_quantile=0.98)" ] }, { "cell_type": "markdown", "id": "06a7f815-c162-4243-97d9-c8e7e84a6b02", "metadata": { "papermill": { "duration": 0.010921, "end_time": "2026-07-28T16:08:59.801097", "exception": false, "start_time": "2026-07-28T16:08:59.790176", "status": "completed" }, "tags": [] }, "source": [ "Add anomalies" ] }, { "cell_type": "code", "execution_count": 34, "id": "e5c7dba4-1ff8-47c9-907b-4bde47ca09dc", "metadata": { "execution": { "iopub.execute_input": "2026-07-28T16:08:59.821815Z", "iopub.status.busy": "2026-07-28T16:08:59.821685Z", "iopub.status.idle": "2026-07-28T16:08:59.824305Z", "shell.execute_reply": "2026-07-28T16:08:59.823853Z" }, "papermill": { "duration": 0.013896, "end_time": "2026-07-28T16:08:59.824798", "exception": false, "start_time": "2026-07-28T16:08:59.810902", "status": "completed" }, "tags": [] }, "outputs": [], "source": [ "import numpy as np\n", "import random\n", "\n", "def add_point_anomalies(ts, n, value):\n", " df = ts.to_dataframe()\n", " random_indices = np.random.choice(df.index, size=n, replace=False)\n", " df.loc[random_indices] = value\n", " return on.TimeSeries.from_dataframe(df)\n", "\n", "def add_collective_anomalies(ts, n, min_duration=10, max_duration=20):\n", " df = ts.to_dataframe()\n", " for i in range(n+1):\n", " block_duration = random.randint(min_duration, max_duration)\n", " start_index = np.random.choice(df.index[:-block_duration])\n", " end_index = start_index + pd.Timedelta(days=block_duration - 1)\n", " df.loc[start_index:end_index] = -40\n", " return on.TimeSeries.from_dataframe(df)" ] }, { "cell_type": "markdown", "id": "610cfd2a-c6eb-45bb-a51d-f384dc5a29e9", "metadata": { "papermill": { "duration": 0.009964, "end_time": "2026-07-28T16:08:59.844714", "exception": false, "start_time": "2026-07-28T16:08:59.834750", "status": "completed" }, "tags": [] }, "source": [ "Select univariate component" ] }, { "cell_type": "code", "execution_count": 35, "id": "9e89c5ca-3456-446c-8b5e-507574f43df5", "metadata": { "execution": { "iopub.execute_input": "2026-07-28T16:08:59.865081Z", "iopub.status.busy": "2026-07-28T16:08:59.864946Z", "iopub.status.idle": "2026-07-28T16:08:59.867998Z", "shell.execute_reply": "2026-07-28T16:08:59.867575Z" }, "papermill": { "duration": 0.014123, "end_time": "2026-07-28T16:08:59.868606", "exception": false, "start_time": "2026-07-28T16:08:59.854483", "status": "completed" }, "tags": [] }, "outputs": [], "source": [ "ts = ts.univariate_component(0)" ] }, { "cell_type": "code", "execution_count": 36, "id": "03364cbd-61aa-4660-9789-ab7f4662ab79", "metadata": { "execution": { "iopub.execute_input": "2026-07-28T16:08:59.888668Z", "iopub.status.busy": "2026-07-28T16:08:59.888561Z", "iopub.status.idle": "2026-07-28T16:08:59.897259Z", "shell.execute_reply": "2026-07-28T16:08:59.896863Z" }, "papermill": { "duration": 0.019558, "end_time": "2026-07-28T16:08:59.897870", "exception": false, "start_time": "2026-07-28T16:08:59.878312", "status": "completed" }, "tags": [] }, "outputs": [], "source": [ "ts = add_point_anomalies(ts, 10, 30)\n", "ts = add_collective_anomalies(ts, 4)" ] }, { "cell_type": "markdown", "id": "370bdde9-662f-43e7-ab93-cd79b8e2f624", "metadata": { "papermill": { "duration": 0.009902, "end_time": "2026-07-28T16:08:59.917819", "exception": false, "start_time": "2026-07-28T16:08:59.907917", "status": "completed" }, "tags": [] }, "source": [ "Create binary time series" ] }, { "cell_type": "code", "execution_count": 37, "id": "4f810223-cfd2-429b-8d7d-6182c26d7246", "metadata": { "execution": { "iopub.execute_input": "2026-07-28T16:08:59.937955Z", "iopub.status.busy": "2026-07-28T16:08:59.937820Z", "iopub.status.idle": "2026-07-28T16:08:59.953583Z", "shell.execute_reply": "2026-07-28T16:08:59.953132Z" }, "papermill": { "duration": 0.026929, "end_time": "2026-07-28T16:08:59.954248", "exception": false, "start_time": "2026-07-28T16:08:59.927319", "status": "completed" }, "tags": [] }, "outputs": [], "source": [ "td_point.fit(ts)\n", "td_contextual.fit(ts)\n", "\n", "ts_ano_point = td_point.detect(ts)\n", "ts_ano_collective = td_collective.detect(ts)\n", "ts_ano_contextual = td_contextual.detect(ts)" ] }, { "cell_type": "code", "execution_count": 38, "id": "c9616b57", "metadata": { "execution": { "iopub.execute_input": "2026-07-28T16:08:59.978266Z", "iopub.status.busy": "2026-07-28T16:08:59.978124Z", "iopub.status.idle": "2026-07-28T16:08:59.986252Z", "shell.execute_reply": "2026-07-28T16:08:59.985623Z" }, "papermill": { "duration": 0.023139, "end_time": "2026-07-28T16:08:59.987149", "exception": false, "start_time": "2026-07-28T16:08:59.964010", "status": "completed" }, "tags": [] }, "outputs": [], "source": [ "ts_ano_point = ts_ano_point.rename({'generation biomass': 'Ponctual anomalies'})\n", "ts_ano_collective = ts_ano_collective.rename({'generation biomass': 'Collective anomalies'})\n", "ts_ano_contextual = ts_ano_contextual.rename({'generation biomass': 'Contextual anomalies'})" ] }, { "cell_type": "markdown", "id": "873160d1-4b22-41c5-b374-67b9f9124754", "metadata": { "papermill": { "duration": 0.030589, "end_time": "2026-07-28T16:09:00.038391", "exception": false, "start_time": "2026-07-28T16:09:00.007802", "status": "completed" }, "tags": [] }, "source": [ "Plot the time series with marked anomalies" ] }, { "cell_type": "code", "execution_count": 39, "id": "2e944b87-b85d-4c5c-b963-857f79e6b2a4", "metadata": { "execution": { "iopub.execute_input": "2026-07-28T16:09:00.062711Z", "iopub.status.busy": "2026-07-28T16:09:00.062565Z", "iopub.status.idle": "2026-07-28T16:09:00.064916Z", "shell.execute_reply": "2026-07-28T16:09:00.064458Z" }, "papermill": { "duration": 0.014522, "end_time": "2026-07-28T16:09:00.065416", "exception": false, "start_time": "2026-07-28T16:09:00.050894", "status": "completed" }, "tags": [] }, "outputs": [], "source": [ "# Define windows for plotting\n", "start = 24 * 7 * 54\n", "duration = 24 * 7 * 15\n", "end = start + duration" ] }, { "cell_type": "code", "execution_count": 40, "id": "d4e93bfd-5e3e-40d4-9c45-577eff06579a", "metadata": { "execution": { "iopub.execute_input": "2026-07-28T16:09:00.091408Z", "iopub.status.busy": "2026-07-28T16:09:00.091265Z", "iopub.status.idle": "2026-07-28T16:09:00.173380Z", "shell.execute_reply": "2026-07-28T16:09:00.172925Z" }, "papermill": { "duration": 0.097672, "end_time": "2026-07-28T16:09:00.176920", "exception": false, "start_time": "2026-07-28T16:09:00.079248", "status": "completed" }, "tags": [] }, "outputs": [ { "data": { "text/html": [ "\n", "\n", "
\n", "" ], "text/plain": [ "alt.LayerChart(...)" ] }, "execution_count": 40, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Actually plot\n", "(\n", "on.Plot(ts[start:end])\n", " .add(on.marks.mark, data=ts_ano_contextual[start:end], type='highlight')\n", " .add(on.marks.mark, data=ts_ano_collective[start:end], type='background')\n", " .add(on.marks.line)\n", " .add(on.marks.mark, data=ts_ano_point[start:end], type='dot')\n", " .properties(width=800, height=200)\n", " .show()\n", ")" ] }, { "cell_type": "markdown", "id": "ba882e58-d1ba-4bd9-9b8b-11c5257986b2", "metadata": { "papermill": { "duration": 0.012205, "end_time": "2026-07-28T16:09:00.201900", "exception": false, "start_time": "2026-07-28T16:09:00.189695", "status": "completed" }, "tags": [] }, "source": [ "### Confidence Intervals" ] }, { "cell_type": "code", "execution_count": 41, "id": "af517b10-9441-4d17-9664-6eb35e4afef3", "metadata": { "execution": { "iopub.execute_input": "2026-07-28T16:09:00.230677Z", "iopub.status.busy": "2026-07-28T16:09:00.230536Z", "iopub.status.idle": "2026-07-28T16:09:00.236462Z", "shell.execute_reply": "2026-07-28T16:09:00.236050Z" }, "papermill": { "duration": 0.020472, "end_time": "2026-07-28T16:09:00.236991", "exception": false, "start_time": "2026-07-28T16:09:00.216519", "status": "completed" }, "tags": [] }, "outputs": [], "source": [ "# Generate two time series\n", "ts1 = on.generators.random_walk().generate(start=pd.Timestamp('2022-01-01'), end=pd.Timestamp('2022-12-31'))\n", "ts2 = on.generators.random_walk().generate(start=pd.Timestamp('2022-01-01'), end=pd.Timestamp('2022-12-31'))" ] }, { "cell_type": "code", "execution_count": 42, "id": "0a73d11f-4b21-45a8-8101-79fa3105d293", "metadata": { "execution": { "iopub.execute_input": "2026-07-28T16:09:00.265208Z", "iopub.status.busy": "2026-07-28T16:09:00.265086Z", "iopub.status.idle": "2026-07-28T16:09:00.271693Z", "shell.execute_reply": "2026-07-28T16:09:00.271348Z" }, "papermill": { "duration": 0.022066, "end_time": "2026-07-28T16:09:00.272445", "exception": false, "start_time": "2026-07-28T16:09:00.250379", "status": "completed" }, "tags": [] }, "outputs": [], "source": [ "# First we create the series with two components\n", "ts1_abs = ts1.map(np.abs)\n", "ts2_abs = ts2.map(np.abs)\n", "ts_ci = concatenate([ts1_abs, ts2_abs], axis=1)\n", "ts_ci = on.TimeSeries.from_darts(ts_ci)\n", "ts_ci = ts_ci.rename({'random_walk': 'CI Upper bound', 'random_walk_1': 'CI Lower bound'})\n", "\n", "# Then the hypothetical measurement\n", "ts_mid = (ts1_abs + ts2_abs) / 2\n", "ts_mid = ts_mid.rename({'random_walk': 'Measurement'})" ] }, { "cell_type": "code", "execution_count": 43, "id": "3a12d720-4522-4aac-ae54-5975b52848aa", "metadata": { "execution": { "iopub.execute_input": "2026-07-28T16:09:00.297559Z", "iopub.status.busy": "2026-07-28T16:09:00.297444Z", "iopub.status.idle": "2026-07-28T16:09:00.331044Z", "shell.execute_reply": "2026-07-28T16:09:00.330583Z" }, "papermill": { "duration": 0.047099, "end_time": "2026-07-28T16:09:00.331769", "exception": false, "start_time": "2026-07-28T16:09:00.284670", "status": "completed" }, "tags": [] }, "outputs": [ { "data": { "text/html": [ "\n", "\n", "
\n", "" ], "text/plain": [ "alt.LayerChart(...)" ] }, "execution_count": 43, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Then we plot it\n", "(\n", "on.Plot() # main line\n", " .add(on.marks.area, ts_ci.head(200), title='Confidence interval')\n", " .add(on.marks.line, ts_mid.head(200))\n", " .properties(width=600, height=200)\n", " .show()\n", ")" ] }, { "cell_type": "markdown", "id": "cd9ce3e4-e4a8-40ca-b128-91b80cf1b933", "metadata": { "papermill": { "duration": 0.01438, "end_time": "2026-07-28T16:09:00.359658", "exception": false, "start_time": "2026-07-28T16:09:00.345278", "status": "completed" }, "tags": [] }, "source": [ "---" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "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.10.0" }, "papermill": { "default_parameters": {}, "duration": 11.458081, "end_time": "2026-07-28T16:09:01.397160", "environment_variables": {}, "exception": null, "input_path": "docs/user_guide/0_core/0.5_plots.ipynb", "output_path": "docs/user_guide/0_core/0.5_plots.ipynb", "parameters": {}, "start_time": "2026-07-28T16:08:49.939079", "version": "2.5.0" } }, "nbformat": 4, "nbformat_minor": 5 }