From 9e8ecf07c7b0591c4b7ff13d2d60ab9e34e960c0 Mon Sep 17 00:00:00 2001 From: Aaron Spring Date: Tue, 14 Feb 2023 22:05:16 +0100 Subject: [PATCH] add `herbie` notebook (#811) --- .binder/environment.yml | 2 +- docs/source/examples.rst | 1 + docs/source/examples/NWP/Herbie.ipynb | 174 ++++++++++++++++++++++++++ 3 files changed, 176 insertions(+), 1 deletion(-) create mode 100644 docs/source/examples/NWP/Herbie.ipynb diff --git a/.binder/environment.yml b/.binder/environment.yml index c395b6e80..c2ea17dc8 100644 --- a/.binder/environment.yml +++ b/.binder/environment.yml @@ -13,7 +13,7 @@ dependencies: - pydap - matplotlib-base - nc-time-axis>=1.4.0 - - netcdf4==1.5.1 # see https://github.com/pydata/xarray/issues/4925 + - netcdf4 # ==1.5.1 # see https://github.com/pydata/xarray/issues/4925 - toolz - xrft - esmtools>=1.1.3 diff --git a/docs/source/examples.rst b/docs/source/examples.rst index 953bba306..58e157137 100644 --- a/docs/source/examples.rst +++ b/docs/source/examples.rst @@ -19,6 +19,7 @@ Numerical Weather Prediction :maxdepth: 1 examples/NWP/NWP_GEFS_6h_forecasts.ipynb + examples/NWP/Herbie.ipynb Subseasonal diff --git a/docs/source/examples/NWP/Herbie.ipynb b/docs/source/examples/NWP/Herbie.ipynb new file mode 100644 index 000000000..55eeb555f --- /dev/null +++ b/docs/source/examples/NWP/Herbie.ipynb @@ -0,0 +1,174 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "9b39af99-1bb7-4fff-be94-85de8dcb7fb8", + "metadata": {}, + "outputs": [], + "source": [ + "!pip install herbie-data --quiet" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "descending-disease", + "metadata": {}, + "outputs": [], + "source": [ + "# linting\n", + "%load_ext nb_black\n", + "%load_ext lab_black" + ] + }, + { + "cell_type": "markdown", + "id": "smart-knock", + "metadata": {}, + "source": [ + "# Skill from ECMWF downloaded with `herbie`\n", + "\n", + "[`herbie`](https://herbie.readthedocs.io/en/latest/user_guide/_tutorial_notebooks/fast.html) downloads forecasts data easily. The resulting datasets is out-of-the-box compatible with `climpred`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "insured-feeding", + "metadata": {}, + "outputs": [], + "source": [ + "import xarray as xr\n", + "import numpy as np\n", + "\n", + "import climpred # forecast verification" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "288c9453-6daa-4ca7-80ba-ef6457e22740", + "metadata": {}, + "outputs": [], + "source": [ + "from herbie import Herbie\n", + "\n", + "H = Herbie(date=\"2022-01-27 00:00\", model=\"ecmwf\", product=\"enfo\", fxx=24 * 1)\n", + "ds = H.xarray(\":2t:\")\n", + "ds" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6b10672b-5374-431d-9b3e-c08c0334aac2", + "metadata": {}, + "outputs": [], + "source": [ + "# take the first with multiple members as forecast\n", + "init = ds[0][[\"t2m\"]]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d537fac9-5a4e-4536-92a3-60ff52818ecf", + "metadata": {}, + "outputs": [], + "source": [ + "H = Herbie(date=\"2022-01-28 00:00\", model=\"ecmwf\", product=\"enfo\", fxx=0)\n", + "ds = H.xarray(\":2t:\")\n", + "ds" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b09be2e9-a7a2-4ab2-9222-49a06524976c", + "metadata": {}, + "outputs": [], + "source": [ + "# take first and make ensemble member mean as observations\n", + "obs = ds[0].mean(\"number\").drop([\"step\", \"valid_time\"]).expand_dims(\"time\")[[\"t2m\"]]" + ] + }, + { + "cell_type": "markdown", + "id": "molecular-chuck", + "metadata": {}, + "source": [ + "## Forecast skill verification\n", + "\n", + "Using using {py:class}`.HindcastEnsemble`.\n", + "\n", + "`climpred` expects `init`, `lead` and optional `member` as dimensions, see [setting-up-your-dataset](setting-up-data.html#setting-up-your-dataset). Existing dimensions are renamed automatically if CF `standard_names` match." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7aa2554a-a9c3-4a8f-a153-ada1d2d71d20", + "metadata": {}, + "outputs": [], + "source": [ + "hindcast = climpred.HindcastEnsemble(\n", + " init.expand_dims([\"time\", \"step\"])\n", + ").add_observations(obs)\n", + "\n", + "hindcast" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "conceptual-richmond", + "metadata": {}, + "outputs": [], + "source": [ + "skill = hindcast.verify(\n", + " metric=\"crps\", comparison=\"m2o\", dim=[\"init\", \"member\"], alignment=\"same_init\"\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "colored-luther", + "metadata": {}, + "outputs": [], + "source": [ + "skill.t2m.plot(robust=True)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cdc2e81e-6a09-4505-98b0-0ea59c827f8b", + "metadata": {}, + "outputs": [], + "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.8" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +}