diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index 2458f1d9..5e83a6f5 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -43,12 +43,8 @@ jobs: # NOTE: login shell activates conda environment shell: bash -el {0} run: | - jupyter-book build ./ --warningiserror --keep-going - - - name: Dump Build Logs - if: always() - run: | - if (test -a _build/html/reports/*log); then cat _build/html/reports/*log ; fi + jupyter-book clean ./ + jupyter-book build ./ - name: Save Build Folder if: always() diff --git a/.github/workflows/pull_request.yaml b/.github/workflows/pull_request.yaml index 2e4a8f43..9c4f92d4 100644 --- a/.github/workflows/pull_request.yaml +++ b/.github/workflows/pull_request.yaml @@ -40,12 +40,8 @@ jobs: - name: Build JupyterBook if: github.event.action != 'closed' run: | - jupyter-book build ./ --warningiserror --keep-going - - - name: Dump Build Logs - if: github.event.action != 'closed' - run: | - if (test -a _build/html/reports/*log); then cat _build/html/reports/*log ; fi + jupyter-book clean ./ + jupyter-book build ./ - name: Upload artifact if: github.event.action != 'closed' diff --git a/.github/workflows/qaqc.yaml b/.github/workflows/qaqc.yaml index ea4d17e0..b6fc2c80 100644 --- a/.github/workflows/qaqc.yaml +++ b/.github/workflows/qaqc.yaml @@ -54,4 +54,5 @@ jobs: timeout-minutes: 5 if: always() run: | + jupyter-book clean ./ jupyter-book build ./ --builder linkcheck diff --git a/_config.yml b/_config.yml index d77f58ec..f500f1d4 100644 --- a/_config.yml +++ b/_config.yml @@ -76,6 +76,28 @@ sphinx: # application/vnd.holoviews_load.v0+json, application/vnd.holoviews_exec.v0+json suppress_warnings: ["mystnb.unknown_mime_type", "misc.highlighting_failure"] codeautolink_concat_default: True + codeautolink_warn_on_missing_inventory: True + codeautolink_warn_on_failed_resolve: True + codeautolink_inventory_map: { + # unfortunately mapping the top level doesn't work, need all methods + #"xarray.core.dataarray.DataArray": "xarray.DataArray", + "xarray.core.accessor_dt.DatetimeAccessor": "xarray.DataArray.dt", + "xarray.core.dataarray.DataArray.coarsen": "xarray.DataArray.coarsen", + "xarray.core.dataarray.DataArray.groupby": "xarray.DataArray.groupby", + "xarray.core.dataarray.DataArray.groupby_bins": "xarray.DataArray.groupby_bins", + "xarray.core.dataarray.DataArray.isel": "xarray.DataArray.isel", + #"xarray.core.dataarray.DataArray.plot": "xarray.DataArray.plot", + "xarray.plot.accessor.DataArrayPlotAccessor": "xarray.DataArray.plot", + "xarray.core.dataarray.DataArray.redindex": "xarray.DataArray.reindex", + "xarray.core.dataarray.DataArray.reduce": "xarray.DataArray.reduce", + "xarray.core.dataarray.DataArray.resample": "xarray.DataArray.resample", + "xarray.core.dataarray.DataArray.rolling": "xarray.DataArray.rolling", + "xarray.core.dataarray.DataArray.sel": "xarray.DataArray.sel", + "xarray.core.dataarray.DataArray.weighted": "xarray.DataArray.weighted", + #"Same for dataset :( + "xarray.core.dataset.Dataset.groupby": "xarray.Dataset.groupby", + "xarray.core.dataset.Dataset.isel": "xarray.Dataset.sel", + } notfound_context: body: "

Whoops! 404 Page Not Found

\n\n

Sorry, this page doesn't exist. Many sections of this book have been updated recently.

Try the search box 🔎 to find what you're looking for!

" notfound_urls_prefix: / diff --git a/_static/style.css b/_static/style.css index b1024666..1e2145b3 100644 --- a/_static/style.css +++ b/_static/style.css @@ -1,3 +1,15 @@ .bd-header-announcement { background-color: var(--pst-color-info-bg); } + +.sphinx-codeautolink-a:link { + border-bottom-color: lightgray; + border-bottom-style: dotted; + border-bottom-width: 1px; +} + +.sphinx-codeautolink-a:hover { + border-bottom-color: rgb(255, 139, 139); + border-bottom-style: dotted; + border-bottom-width: 1px; +} diff --git a/intermediate/01-high-level-computation-patterns.ipynb b/intermediate/01-high-level-computation-patterns.ipynb index e5f17c1c..77fe829e 100644 --- a/intermediate/01-high-level-computation-patterns.ipynb +++ b/intermediate/01-high-level-computation-patterns.ipynb @@ -97,39 +97,36 @@ ] }, { - "cell_type": "markdown", + "cell_type": "code", + "execution_count": null, "id": "3", "metadata": { - "slideshow": { - "slide_type": "slide" - }, "tags": [] }, + "outputs": [], "source": [ - "### Load example dataset\n" + "import numpy as np\n", + "import xarray as xr\n", + "import matplotlib.pyplot as plt\n", + "\n", + "# reduce figure filesize (default=100)\n", + "plt.rcParams[\"figure.dpi\"] = 90\n", + "xr.set_options(keep_attrs=True, display_expand_data=False);" ] }, { - "cell_type": "code", - "execution_count": null, + "cell_type": "markdown", "id": "4", "metadata": { + "slideshow": { + "slide_type": "slide" + }, "tags": [] }, - "outputs": [], "source": [ - "import numpy as np\n", - "import xarray as xr\n", - "import matplotlib.pyplot as plt\n", - "\n", - "# reduce figure size\n", - "plt.rcParams[\"figure.dpi\"] = 90\n", - "xr.set_options(keep_attrs=True, display_expand_data=False)\n", + "### Load example dataset\n", "\n", - "da = xr.tutorial.load_dataset(\"air_temperature\", engine=\"netcdf4\").air\n", - "monthly = da.resample(time=\"ME\").mean()\n", - "data = da.isel(time=0)\n", - "data.plot();" + "We will use the Xarray Tutorial Air Temperature dataset in this notebook. In the following cells we quickly load, look at the data structure and make a plot. We use [Python Type Hints](https://docs.python.org/3/library/typing.html) to be explicit that `da` and `data` variables used throughout this notebook are xarray DataArrays (this is optional!).\n" ] }, { @@ -141,13 +138,26 @@ }, "outputs": [], "source": [ + "da: xr.DataArray = xr.tutorial.load_dataset(\"air_temperature\", engine=\"netcdf4\").air\n", "da" ] }, { - "cell_type": "markdown", + "cell_type": "code", + "execution_count": null, "id": "6", "metadata": {}, + "outputs": [], + "source": [ + "monthly = da.resample(time=\"ME\").mean()\n", + "data: xr.DataArray = da.isel(time=0)\n", + "data.plot();" + ] + }, + { + "cell_type": "markdown", + "id": "7", + "metadata": {}, "source": [ "***\n", "\n", @@ -163,7 +173,7 @@ { "cell_type": "code", "execution_count": null, - "id": "7", + "id": "8", "metadata": { "tags": [] }, @@ -186,7 +196,7 @@ }, { "cell_type": "markdown", - "id": "8", + "id": "9", "metadata": {}, "source": [ "This pattern is the GroupBy pattern.\n", @@ -198,7 +208,7 @@ { "cell_type": "code", "execution_count": null, - "id": "9", + "id": "10", "metadata": { "tags": [] }, @@ -214,7 +224,7 @@ }, { "cell_type": "markdown", - "id": "10", + "id": "11", "metadata": {}, "source": [ "Writing a for-loop here is not wrong, but it can quickly become cumbersome if you have a complex function to apply and it will take a while to compute on a large dataset (you may even run out of memory). Parallelizing the computation would take a lot of additional work.\n", @@ -225,7 +235,7 @@ { "cell_type": "code", "execution_count": null, - "id": "11", + "id": "12", "metadata": {}, "outputs": [], "source": [ @@ -237,7 +247,7 @@ }, { "cell_type": "markdown", - "id": "12", + "id": "13", "metadata": {}, "source": [ "```{note}\n", @@ -258,7 +268,7 @@ }, { "cell_type": "markdown", - "id": "13", + "id": "14", "metadata": { "slideshow": { "slide_type": "slide" @@ -274,7 +284,7 @@ { "cell_type": "code", "execution_count": null, - "id": "14", + "id": "15", "metadata": {}, "outputs": [], "source": [ @@ -284,7 +294,7 @@ { "cell_type": "code", "execution_count": null, - "id": "15", + "id": "16", "metadata": { "tags": [] }, @@ -297,7 +307,7 @@ { "cell_type": "code", "execution_count": null, - "id": "16", + "id": "17", "metadata": { "tags": [] }, @@ -310,7 +320,7 @@ { "cell_type": "code", "execution_count": null, - "id": "17", + "id": "18", "metadata": { "tags": [] }, @@ -323,7 +333,7 @@ { "cell_type": "code", "execution_count": null, - "id": "18", + "id": "19", "metadata": { "slideshow": { "slide_type": "subslide" @@ -341,7 +351,7 @@ }, { "cell_type": "markdown", - "id": "19", + "id": "20", "metadata": {}, "source": [ "***\n", @@ -371,7 +381,7 @@ }, { "cell_type": "markdown", - "id": "20", + "id": "21", "metadata": { "slideshow": { "slide_type": "subslide" @@ -398,7 +408,7 @@ { "cell_type": "code", "execution_count": null, - "id": "21", + "id": "22", "metadata": {}, "outputs": [], "source": [ @@ -407,7 +417,7 @@ }, { "cell_type": "markdown", - "id": "22", + "id": "23", "metadata": {}, "source": [ "And now smoothed 5 point running mean in lat and lon\n" @@ -416,7 +426,7 @@ { "cell_type": "code", "execution_count": null, - "id": "23", + "id": "24", "metadata": {}, "outputs": [], "source": [ @@ -425,7 +435,7 @@ }, { "cell_type": "markdown", - "id": "24", + "id": "25", "metadata": { "slideshow": { "slide_type": "subslide" @@ -445,7 +455,7 @@ { "cell_type": "code", "execution_count": null, - "id": "25", + "id": "26", "metadata": {}, "outputs": [], "source": [ @@ -454,7 +464,7 @@ }, { "cell_type": "markdown", - "id": "26", + "id": "27", "metadata": {}, "source": [ "::::{admonition} Exercise\n", @@ -476,7 +486,7 @@ }, { "cell_type": "markdown", - "id": "27", + "id": "28", "metadata": { "slideshow": { "slide_type": "subslide" @@ -492,7 +502,7 @@ { "cell_type": "code", "execution_count": null, - "id": "28", + "id": "29", "metadata": {}, "outputs": [], "source": [ @@ -503,7 +513,7 @@ { "cell_type": "code", "execution_count": null, - "id": "29", + "id": "30", "metadata": {}, "outputs": [], "source": [ @@ -513,7 +523,7 @@ }, { "cell_type": "markdown", - "id": "30", + "id": "31", "metadata": {}, "source": [ "```{note}\n", @@ -523,7 +533,7 @@ }, { "cell_type": "markdown", - "id": "31", + "id": "32", "metadata": {}, "source": [ "::::{admonition} Exercise\n", @@ -542,7 +552,7 @@ }, { "cell_type": "markdown", - "id": "32", + "id": "33", "metadata": {}, "source": [ "`construct` is clever.\n", @@ -554,7 +564,7 @@ }, { "cell_type": "markdown", - "id": "33", + "id": "34", "metadata": { "tags": [] }, @@ -567,7 +577,7 @@ { "cell_type": "code", "execution_count": null, - "id": "34", + "id": "35", "metadata": {}, "outputs": [], "source": [ @@ -576,7 +586,7 @@ }, { "cell_type": "markdown", - "id": "35", + "id": "36", "metadata": { "slideshow": { "slide_type": "subslide" @@ -600,7 +610,7 @@ { "cell_type": "code", "execution_count": null, - "id": "36", + "id": "37", "metadata": {}, "outputs": [], "source": [ @@ -610,7 +620,7 @@ { "cell_type": "code", "execution_count": null, - "id": "37", + "id": "38", "metadata": {}, "outputs": [], "source": [ @@ -620,7 +630,7 @@ { "cell_type": "code", "execution_count": null, - "id": "38", + "id": "39", "metadata": {}, "outputs": [], "source": [ @@ -630,16 +640,16 @@ { "cell_type": "code", "execution_count": null, - "id": "39", + "id": "40", "metadata": {}, "outputs": [], "source": [ - "(data.coarsen(lat=5, lon=5, boundary=\"trim\").mean().plot())" + "(data.coarsen(lat=5, lon=5, boundary=\"trim\").mean().plot());" ] }, { "cell_type": "markdown", - "id": "40", + "id": "41", "metadata": { "slideshow": { "slide_type": "subslide" @@ -665,7 +675,7 @@ }, { "cell_type": "markdown", - "id": "41", + "id": "42", "metadata": { "slideshow": { "slide_type": "subslide" @@ -685,7 +695,7 @@ { "cell_type": "code", "execution_count": null, - "id": "42", + "id": "43", "metadata": {}, "outputs": [], "source": [ @@ -700,7 +710,7 @@ { "cell_type": "code", "execution_count": null, - "id": "43", + "id": "44", "metadata": {}, "outputs": [], "source": [ @@ -710,7 +720,7 @@ }, { "cell_type": "markdown", - "id": "44", + "id": "45", "metadata": {}, "source": [ "Note two things:\n", @@ -725,7 +735,7 @@ { "cell_type": "code", "execution_count": null, - "id": "45", + "id": "46", "metadata": {}, "outputs": [], "source": [ @@ -734,7 +744,7 @@ }, { "cell_type": "markdown", - "id": "46", + "id": "47", "metadata": {}, "source": [ "This adds values at the end of the array (see the 'nan' at the end of the time coordinate?), which is not so sensible for this\n", @@ -744,7 +754,7 @@ { "cell_type": "code", "execution_count": null, - "id": "47", + "id": "48", "metadata": {}, "outputs": [], "source": [ @@ -755,7 +765,7 @@ }, { "cell_type": "markdown", - "id": "48", + "id": "49", "metadata": {}, "source": [ "Note that `coarsen` pads with NaNs. For more control over padding, use\n", @@ -765,7 +775,7 @@ { "cell_type": "code", "execution_count": null, - "id": "49", + "id": "50", "metadata": {}, "outputs": [], "source": [ @@ -779,7 +789,7 @@ }, { "cell_type": "markdown", - "id": "50", + "id": "51", "metadata": {}, "source": [ "```{note}\n", @@ -790,7 +800,7 @@ }, { "cell_type": "markdown", - "id": "51", + "id": "52", "metadata": {}, "source": [ ":::{admonition} Exercise\n", @@ -834,7 +844,7 @@ }, { "cell_type": "markdown", - "id": "52", + "id": "53", "metadata": {}, "source": [ "::::{admonition} Exercise\n", @@ -859,7 +869,7 @@ }, { "cell_type": "markdown", - "id": "53", + "id": "54", "metadata": {}, "source": [ "### Summary\n", @@ -875,7 +885,7 @@ }, { "cell_type": "markdown", - "id": "54", + "id": "55", "metadata": { "slideshow": { "slide_type": "slide" @@ -921,7 +931,7 @@ { "cell_type": "code", "execution_count": null, - "id": "55", + "id": "56", "metadata": {}, "outputs": [], "source": [ @@ -932,7 +942,7 @@ { "cell_type": "code", "execution_count": null, - "id": "56", + "id": "57", "metadata": {}, "outputs": [], "source": [ @@ -945,7 +955,7 @@ { "cell_type": "code", "execution_count": null, - "id": "57", + "id": "58", "metadata": {}, "outputs": [], "source": [ @@ -956,7 +966,7 @@ }, { "cell_type": "markdown", - "id": "58", + "id": "59", "metadata": {}, "source": [ "Notice that since we have averaged over all the years for each month, our resulting DataArray no longer has a \"year\" coordinate.\n", @@ -967,7 +977,7 @@ { "cell_type": "code", "execution_count": null, - "id": "59", + "id": "60", "metadata": {}, "outputs": [], "source": [ @@ -976,7 +986,7 @@ }, { "cell_type": "markdown", - "id": "60", + "id": "61", "metadata": {}, "source": [ "Similarly for binning (remember this is useful when the parameter you are binning over is not \"exact\", like a float),\n" @@ -985,7 +995,7 @@ { "cell_type": "code", "execution_count": null, - "id": "61", + "id": "62", "metadata": {}, "outputs": [], "source": [ @@ -994,7 +1004,7 @@ }, { "cell_type": "markdown", - "id": "62", + "id": "63", "metadata": {}, "source": [ "and resampling...\n" @@ -1003,7 +1013,7 @@ { "cell_type": "code", "execution_count": null, - "id": "63", + "id": "64", "metadata": {}, "outputs": [], "source": [ @@ -1012,7 +1022,7 @@ }, { "cell_type": "markdown", - "id": "64", + "id": "65", "metadata": {}, "source": [ "```{note}\n", @@ -1024,7 +1034,7 @@ }, { "cell_type": "markdown", - "id": "65", + "id": "66", "metadata": { "slideshow": { "slide_type": "subslide" @@ -1058,7 +1068,7 @@ }, { "cell_type": "markdown", - "id": "66", + "id": "67", "metadata": { "slideshow": { "slide_type": "subslide" @@ -1077,7 +1087,7 @@ { "cell_type": "code", "execution_count": null, - "id": "67", + "id": "68", "metadata": { "tags": [] }, @@ -1089,7 +1099,7 @@ { "cell_type": "code", "execution_count": null, - "id": "68", + "id": "69", "metadata": {}, "outputs": [], "source": [ @@ -1099,7 +1109,7 @@ { "cell_type": "code", "execution_count": null, - "id": "69", + "id": "70", "metadata": {}, "outputs": [], "source": [ @@ -1109,7 +1119,7 @@ { "cell_type": "code", "execution_count": null, - "id": "70", + "id": "71", "metadata": {}, "outputs": [], "source": [ @@ -1118,7 +1128,7 @@ }, { "cell_type": "markdown", - "id": "71", + "id": "72", "metadata": {}, "source": [ "#### Construct and use custom labels\n", @@ -1133,7 +1143,7 @@ { "cell_type": "code", "execution_count": null, - "id": "72", + "id": "73", "metadata": {}, "outputs": [], "source": [ @@ -1143,7 +1153,7 @@ }, { "cell_type": "markdown", - "id": "73", + "id": "74", "metadata": {}, "source": [ "Create a new empty array\n" @@ -1152,7 +1162,7 @@ { "cell_type": "code", "execution_count": null, - "id": "74", + "id": "75", "metadata": {}, "outputs": [], "source": [ @@ -1162,7 +1172,7 @@ }, { "cell_type": "markdown", - "id": "75", + "id": "76", "metadata": {}, "source": [ "Use `isin` to assign custom seasons,\n" @@ -1171,7 +1181,7 @@ { "cell_type": "code", "execution_count": null, - "id": "76", + "id": "77", "metadata": {}, "outputs": [], "source": [ @@ -1183,7 +1193,7 @@ }, { "cell_type": "markdown", - "id": "77", + "id": "78", "metadata": {}, "source": [ "Turn our new seasonal group array into a DataArray." @@ -1192,7 +1202,7 @@ { "cell_type": "code", "execution_count": null, - "id": "78", + "id": "79", "metadata": {}, "outputs": [], "source": [ @@ -1203,7 +1213,7 @@ { "cell_type": "code", "execution_count": null, - "id": "79", + "id": "80", "metadata": {}, "outputs": [], "source": [ @@ -1219,7 +1229,7 @@ }, { "cell_type": "markdown", - "id": "80", + "id": "81", "metadata": { "slideshow": { "slide_type": "subslide" @@ -1235,7 +1245,7 @@ { "cell_type": "code", "execution_count": null, - "id": "81", + "id": "82", "metadata": {}, "outputs": [], "source": [ @@ -1245,7 +1255,7 @@ { "cell_type": "code", "execution_count": null, - "id": "82", + "id": "83", "metadata": {}, "outputs": [], "source": [ @@ -1256,7 +1266,7 @@ }, { "cell_type": "markdown", - "id": "83", + "id": "84", "metadata": { "slideshow": { "slide_type": "subslide" @@ -1274,7 +1284,7 @@ { "cell_type": "code", "execution_count": null, - "id": "84", + "id": "85", "metadata": {}, "outputs": [], "source": [ @@ -1283,7 +1293,7 @@ }, { "cell_type": "markdown", - "id": "85", + "id": "86", "metadata": { "tags": [] }, @@ -1296,7 +1306,7 @@ { "cell_type": "code", "execution_count": null, - "id": "86", + "id": "87", "metadata": {}, "outputs": [], "source": [ @@ -1305,7 +1315,7 @@ }, { "cell_type": "markdown", - "id": "87", + "id": "88", "metadata": {}, "source": [ "```{tip}\n", @@ -1315,7 +1325,7 @@ }, { "cell_type": "markdown", - "id": "88", + "id": "89", "metadata": { "tags": [] }, @@ -1334,7 +1344,7 @@ { "cell_type": "code", "execution_count": null, - "id": "89", + "id": "90", "metadata": {}, "outputs": [], "source": [ @@ -1344,7 +1354,7 @@ }, { "cell_type": "markdown", - "id": "90", + "id": "91", "metadata": {}, "source": [ "`group` is a DataArray containing data for all December days (because the last printed `label` value is `12`, so the last `group` value is for December)." @@ -1353,7 +1363,7 @@ { "cell_type": "code", "execution_count": null, - "id": "91", + "id": "92", "metadata": { "tags": [] }, @@ -1364,7 +1374,7 @@ }, { "cell_type": "markdown", - "id": "92", + "id": "93", "metadata": {}, "source": [ "Maybe you want a histogram of December temperatures?\n" @@ -1373,7 +1383,7 @@ { "cell_type": "code", "execution_count": null, - "id": "93", + "id": "94", "metadata": {}, "outputs": [], "source": [ @@ -1382,7 +1392,7 @@ }, { "cell_type": "markdown", - "id": "94", + "id": "95", "metadata": {}, "source": [ "Remember, this example is just to show how you could operate on each group object in a groupby operation. If we wanted to just explore the December (or March) data, we should just filter for it directly:" @@ -1391,7 +1401,7 @@ { "cell_type": "code", "execution_count": null, - "id": "95", + "id": "96", "metadata": {}, "outputs": [], "source": [ @@ -1400,7 +1410,7 @@ }, { "cell_type": "markdown", - "id": "96", + "id": "97", "metadata": { "tags": [] }, @@ -1418,7 +1428,7 @@ { "cell_type": "code", "execution_count": null, - "id": "97", + "id": "98", "metadata": { "tags": [] }, @@ -1434,7 +1444,7 @@ }, { "cell_type": "markdown", - "id": "98", + "id": "99", "metadata": {}, "source": [ "***" @@ -1442,7 +1452,7 @@ }, { "cell_type": "markdown", - "id": "99", + "id": "100", "metadata": {}, "source": [ "## Summary\n",