Last active
July 13, 2022 02:08
-
-
Save jbusecke/9498cd68bd358084f0d96c9009043f58 to your computer and use it in GitHub Desktop.
CMIP6 Oxygen Minimum Zones with pyvista-xarray
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"cells": [ | |
{ | |
"cell_type": "markdown", | |
"id": "224f7cb6-ae55-426f-90f4-e64e9dbf5f52", | |
"metadata": {}, | |
"source": [ | |
"# Visualizing CMIP6 data in the cloud using pyvista-xarray" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 2, | |
"id": "353bc34a-af6f-402e-afd6-d78c1d19b3e9", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"# environment is based of the pyvista tutorial. \n", | |
"# TO run locally do: \n", | |
"# mamba install -c conda-forge pyvista\n", | |
"# mamba install -c conda-forge jupyterlab pythreejs ipyvtklink panel xmip intake-esm gcsfs pyvista-xarray cf_xarray -y" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 1, | |
"id": "fc877b48-ea21-439c-9412-7e7d4241973e", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"# !xmip intake-esm gcsfs pyvista-xarray cf_xarray -y" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "5846b9c1-9c49-4a34-9cd5-4d36620e34e3", | |
"metadata": {}, | |
"source": [ | |
"## Load an example dataset\n", | |
"\n", | |
"This is a publically available dataset on GCS. More info on this [here](https://pangeo-data.github.io/pangeo-cmip6-cloud/accessing_data.html)." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 4, | |
"id": "4940a2a5-4efa-42f8-87a9-7ca3625fbc41", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"\n", | |
"--> The keys in the returned dictionary of datasets are constructed as follows:\n", | |
"\t'activity_id.institution_id.source_id.experiment_id.table_id.grid_label'\n" | |
] | |
}, | |
{ | |
"data": { | |
"text/html": [ | |
"\n", | |
"<style>\n", | |
" /* Turns off some styling */\n", | |
" progress {\n", | |
" /* gets rid of default border in Firefox and Opera. */\n", | |
" border: none;\n", | |
" /* Needs to be in here for Safari polyfill so background images work as expected. */\n", | |
" background-size: auto;\n", | |
" }\n", | |
" .progress-bar-interrupted, .progress-bar-interrupted::-webkit-progress-bar {\n", | |
" background: #F44336;\n", | |
" }\n", | |
"</style>\n" | |
], | |
"text/plain": [ | |
"<IPython.core.display.HTML object>" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
}, | |
{ | |
"data": { | |
"text/html": [ | |
"\n", | |
" <div>\n", | |
" <progress value='1' class='' max='1' style='width:300px; height:20px; vertical-align: middle;'></progress>\n", | |
" 100.00% [1/1 00:00<00:00]\n", | |
" </div>\n", | |
" " | |
], | |
"text/plain": [ | |
"<IPython.core.display.HTML object>" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"from xmip.utils import google_cmip_col\n", | |
"from xmip.preprocessing import combined_preprocessing\n", | |
"\n", | |
"col = google_cmip_col()\n", | |
"cat = col.search(\n", | |
" source_id='GFDL-ESM4',\n", | |
" experiment_id='historical',\n", | |
" table_id='Omon',\n", | |
" variable_id='o2',\n", | |
")\n", | |
"ddict = cat.to_dataset_dict(preprocess=combined_preprocessing)\n", | |
"ds = ddict['CMIP.NOAA-GFDL.GFDL-ESM4.historical.Omon.gr']" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "11831ea7-6b3a-4716-bca4-85374713174f", | |
"metadata": {}, | |
"source": [ | |
"## Prep data for visualization" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 27, | |
"id": "45a9b6e0-75c7-4479-83cf-cae164d5461d", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"import pvxarray\n", | |
"import pyvista as pv\n", | |
"import xarray as xr\n", | |
"import numpy as np" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 17, | |
"id": "14b49227-41e6-4e76-ae17-a005669cba13", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/html": [ | |
"<div><svg style=\"position: absolute; width: 0; height: 0; overflow: hidden\">\n", | |
"<defs>\n", | |
"<symbol id=\"icon-database\" viewBox=\"0 0 32 32\">\n", | |
"<path d=\"M16 0c-8.837 0-16 2.239-16 5v4c0 2.761 7.163 5 16 5s16-2.239 16-5v-4c0-2.761-7.163-5-16-5z\"></path>\n", | |
"<path d=\"M16 17c-8.837 0-16-2.239-16-5v6c0 2.761 7.163 5 16 5s16-2.239 16-5v-6c0 2.761-7.163 5-16 5z\"></path>\n", | |
"<path d=\"M16 26c-8.837 0-16-2.239-16-5v6c0 2.761 7.163 5 16 5s16-2.239 16-5v-6c0 2.761-7.163 5-16 5z\"></path>\n", | |
"</symbol>\n", | |
"<symbol id=\"icon-file-text2\" viewBox=\"0 0 32 32\">\n", | |
"<path d=\"M28.681 7.159c-0.694-0.947-1.662-2.053-2.724-3.116s-2.169-2.030-3.116-2.724c-1.612-1.182-2.393-1.319-2.841-1.319h-15.5c-1.378 0-2.5 1.121-2.5 2.5v27c0 1.378 1.122 2.5 2.5 2.5h23c1.378 0 2.5-1.122 2.5-2.5v-19.5c0-0.448-0.137-1.23-1.319-2.841zM24.543 5.457c0.959 0.959 1.712 1.825 2.268 2.543h-4.811v-4.811c0.718 0.556 1.584 1.309 2.543 2.268zM28 29.5c0 0.271-0.229 0.5-0.5 0.5h-23c-0.271 0-0.5-0.229-0.5-0.5v-27c0-0.271 0.229-0.5 0.5-0.5 0 0 15.499-0 15.5 0v7c0 0.552 0.448 1 1 1h7v19.5z\"></path>\n", | |
"<path d=\"M23 26h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z\"></path>\n", | |
"<path d=\"M23 22h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z\"></path>\n", | |
"<path d=\"M23 18h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z\"></path>\n", | |
"</symbol>\n", | |
"</defs>\n", | |
"</svg>\n", | |
"<style>/* CSS stylesheet for displaying xarray objects in jupyterlab.\n", | |
" *\n", | |
" */\n", | |
"\n", | |
":root {\n", | |
" --xr-font-color0: var(--jp-content-font-color0, rgba(0, 0, 0, 1));\n", | |
" --xr-font-color2: var(--jp-content-font-color2, rgba(0, 0, 0, 0.54));\n", | |
" --xr-font-color3: var(--jp-content-font-color3, rgba(0, 0, 0, 0.38));\n", | |
" --xr-border-color: var(--jp-border-color2, #e0e0e0);\n", | |
" --xr-disabled-color: var(--jp-layout-color3, #bdbdbd);\n", | |
" --xr-background-color: var(--jp-layout-color0, white);\n", | |
" --xr-background-color-row-even: var(--jp-layout-color1, white);\n", | |
" --xr-background-color-row-odd: var(--jp-layout-color2, #eeeeee);\n", | |
"}\n", | |
"\n", | |
"html[theme=dark],\n", | |
"body.vscode-dark {\n", | |
" --xr-font-color0: rgba(255, 255, 255, 1);\n", | |
" --xr-font-color2: rgba(255, 255, 255, 0.54);\n", | |
" --xr-font-color3: rgba(255, 255, 255, 0.38);\n", | |
" --xr-border-color: #1F1F1F;\n", | |
" --xr-disabled-color: #515151;\n", | |
" --xr-background-color: #111111;\n", | |
" --xr-background-color-row-even: #111111;\n", | |
" --xr-background-color-row-odd: #313131;\n", | |
"}\n", | |
"\n", | |
".xr-wrap {\n", | |
" display: block !important;\n", | |
" min-width: 300px;\n", | |
" max-width: 700px;\n", | |
"}\n", | |
"\n", | |
".xr-text-repr-fallback {\n", | |
" /* fallback to plain text repr when CSS is not injected (untrusted notebook) */\n", | |
" display: none;\n", | |
"}\n", | |
"\n", | |
".xr-header {\n", | |
" padding-top: 6px;\n", | |
" padding-bottom: 6px;\n", | |
" margin-bottom: 4px;\n", | |
" border-bottom: solid 1px var(--xr-border-color);\n", | |
"}\n", | |
"\n", | |
".xr-header > div,\n", | |
".xr-header > ul {\n", | |
" display: inline;\n", | |
" margin-top: 0;\n", | |
" margin-bottom: 0;\n", | |
"}\n", | |
"\n", | |
".xr-obj-type,\n", | |
".xr-array-name {\n", | |
" margin-left: 2px;\n", | |
" margin-right: 10px;\n", | |
"}\n", | |
"\n", | |
".xr-obj-type {\n", | |
" color: var(--xr-font-color2);\n", | |
"}\n", | |
"\n", | |
".xr-sections {\n", | |
" padding-left: 0 !important;\n", | |
" display: grid;\n", | |
" grid-template-columns: 150px auto auto 1fr 20px 20px;\n", | |
"}\n", | |
"\n", | |
".xr-section-item {\n", | |
" display: contents;\n", | |
"}\n", | |
"\n", | |
".xr-section-item input {\n", | |
" display: none;\n", | |
"}\n", | |
"\n", | |
".xr-section-item input + label {\n", | |
" color: var(--xr-disabled-color);\n", | |
"}\n", | |
"\n", | |
".xr-section-item input:enabled + label {\n", | |
" cursor: pointer;\n", | |
" color: var(--xr-font-color2);\n", | |
"}\n", | |
"\n", | |
".xr-section-item input:enabled + label:hover {\n", | |
" color: var(--xr-font-color0);\n", | |
"}\n", | |
"\n", | |
".xr-section-summary {\n", | |
" grid-column: 1;\n", | |
" color: var(--xr-font-color2);\n", | |
" font-weight: 500;\n", | |
"}\n", | |
"\n", | |
".xr-section-summary > span {\n", | |
" display: inline-block;\n", | |
" padding-left: 0.5em;\n", | |
"}\n", | |
"\n", | |
".xr-section-summary-in:disabled + label {\n", | |
" color: var(--xr-font-color2);\n", | |
"}\n", | |
"\n", | |
".xr-section-summary-in + label:before {\n", | |
" display: inline-block;\n", | |
" content: '►';\n", | |
" font-size: 11px;\n", | |
" width: 15px;\n", | |
" text-align: center;\n", | |
"}\n", | |
"\n", | |
".xr-section-summary-in:disabled + label:before {\n", | |
" color: var(--xr-disabled-color);\n", | |
"}\n", | |
"\n", | |
".xr-section-summary-in:checked + label:before {\n", | |
" content: '▼';\n", | |
"}\n", | |
"\n", | |
".xr-section-summary-in:checked + label > span {\n", | |
" display: none;\n", | |
"}\n", | |
"\n", | |
".xr-section-summary,\n", | |
".xr-section-inline-details {\n", | |
" padding-top: 4px;\n", | |
" padding-bottom: 4px;\n", | |
"}\n", | |
"\n", | |
".xr-section-inline-details {\n", | |
" grid-column: 2 / -1;\n", | |
"}\n", | |
"\n", | |
".xr-section-details {\n", | |
" display: none;\n", | |
" grid-column: 1 / -1;\n", | |
" margin-bottom: 5px;\n", | |
"}\n", | |
"\n", | |
".xr-section-summary-in:checked ~ .xr-section-details {\n", | |
" display: contents;\n", | |
"}\n", | |
"\n", | |
".xr-array-wrap {\n", | |
" grid-column: 1 / -1;\n", | |
" display: grid;\n", | |
" grid-template-columns: 20px auto;\n", | |
"}\n", | |
"\n", | |
".xr-array-wrap > label {\n", | |
" grid-column: 1;\n", | |
" vertical-align: top;\n", | |
"}\n", | |
"\n", | |
".xr-preview {\n", | |
" color: var(--xr-font-color3);\n", | |
"}\n", | |
"\n", | |
".xr-array-preview,\n", | |
".xr-array-data {\n", | |
" padding: 0 5px !important;\n", | |
" grid-column: 2;\n", | |
"}\n", | |
"\n", | |
".xr-array-data,\n", | |
".xr-array-in:checked ~ .xr-array-preview {\n", | |
" display: none;\n", | |
"}\n", | |
"\n", | |
".xr-array-in:checked ~ .xr-array-data,\n", | |
".xr-array-preview {\n", | |
" display: inline-block;\n", | |
"}\n", | |
"\n", | |
".xr-dim-list {\n", | |
" display: inline-block !important;\n", | |
" list-style: none;\n", | |
" padding: 0 !important;\n", | |
" margin: 0;\n", | |
"}\n", | |
"\n", | |
".xr-dim-list li {\n", | |
" display: inline-block;\n", | |
" padding: 0;\n", | |
" margin: 0;\n", | |
"}\n", | |
"\n", | |
".xr-dim-list:before {\n", | |
" content: '(';\n", | |
"}\n", | |
"\n", | |
".xr-dim-list:after {\n", | |
" content: ')';\n", | |
"}\n", | |
"\n", | |
".xr-dim-list li:not(:last-child):after {\n", | |
" content: ',';\n", | |
" padding-right: 5px;\n", | |
"}\n", | |
"\n", | |
".xr-has-index {\n", | |
" font-weight: bold;\n", | |
"}\n", | |
"\n", | |
".xr-var-list,\n", | |
".xr-var-item {\n", | |
" display: contents;\n", | |
"}\n", | |
"\n", | |
".xr-var-item > div,\n", | |
".xr-var-item label,\n", | |
".xr-var-item > .xr-var-name span {\n", | |
" background-color: var(--xr-background-color-row-even);\n", | |
" margin-bottom: 0;\n", | |
"}\n", | |
"\n", | |
".xr-var-item > .xr-var-name:hover span {\n", | |
" padding-right: 5px;\n", | |
"}\n", | |
"\n", | |
".xr-var-list > li:nth-child(odd) > div,\n", | |
".xr-var-list > li:nth-child(odd) > label,\n", | |
".xr-var-list > li:nth-child(odd) > .xr-var-name span {\n", | |
" background-color: var(--xr-background-color-row-odd);\n", | |
"}\n", | |
"\n", | |
".xr-var-name {\n", | |
" grid-column: 1;\n", | |
"}\n", | |
"\n", | |
".xr-var-dims {\n", | |
" grid-column: 2;\n", | |
"}\n", | |
"\n", | |
".xr-var-dtype {\n", | |
" grid-column: 3;\n", | |
" text-align: right;\n", | |
" color: var(--xr-font-color2);\n", | |
"}\n", | |
"\n", | |
".xr-var-preview {\n", | |
" grid-column: 4;\n", | |
"}\n", | |
"\n", | |
".xr-var-name,\n", | |
".xr-var-dims,\n", | |
".xr-var-dtype,\n", | |
".xr-preview,\n", | |
".xr-attrs dt {\n", | |
" white-space: nowrap;\n", | |
" overflow: hidden;\n", | |
" text-overflow: ellipsis;\n", | |
" padding-right: 10px;\n", | |
"}\n", | |
"\n", | |
".xr-var-name:hover,\n", | |
".xr-var-dims:hover,\n", | |
".xr-var-dtype:hover,\n", | |
".xr-attrs dt:hover {\n", | |
" overflow: visible;\n", | |
" width: auto;\n", | |
" z-index: 1;\n", | |
"}\n", | |
"\n", | |
".xr-var-attrs,\n", | |
".xr-var-data {\n", | |
" display: none;\n", | |
" background-color: var(--xr-background-color) !important;\n", | |
" padding-bottom: 5px !important;\n", | |
"}\n", | |
"\n", | |
".xr-var-attrs-in:checked ~ .xr-var-attrs,\n", | |
".xr-var-data-in:checked ~ .xr-var-data {\n", | |
" display: block;\n", | |
"}\n", | |
"\n", | |
".xr-var-data > table {\n", | |
" float: right;\n", | |
"}\n", | |
"\n", | |
".xr-var-name span,\n", | |
".xr-var-data,\n", | |
".xr-attrs {\n", | |
" padding-left: 25px !important;\n", | |
"}\n", | |
"\n", | |
".xr-attrs,\n", | |
".xr-var-attrs,\n", | |
".xr-var-data {\n", | |
" grid-column: 1 / -1;\n", | |
"}\n", | |
"\n", | |
"dl.xr-attrs {\n", | |
" padding: 0;\n", | |
" margin: 0;\n", | |
" display: grid;\n", | |
" grid-template-columns: 125px auto;\n", | |
"}\n", | |
"\n", | |
".xr-attrs dt,\n", | |
".xr-attrs dd {\n", | |
" padding: 0;\n", | |
" margin: 0;\n", | |
" float: left;\n", | |
" padding-right: 10px;\n", | |
" width: auto;\n", | |
"}\n", | |
"\n", | |
".xr-attrs dt {\n", | |
" font-weight: normal;\n", | |
" grid-column: 1;\n", | |
"}\n", | |
"\n", | |
".xr-attrs dt:hover span {\n", | |
" display: inline-block;\n", | |
" background: var(--xr-background-color);\n", | |
" padding-right: 10px;\n", | |
"}\n", | |
"\n", | |
".xr-attrs dd {\n", | |
" grid-column: 2;\n", | |
" white-space: pre-wrap;\n", | |
" word-break: break-all;\n", | |
"}\n", | |
"\n", | |
".xr-icon-database,\n", | |
".xr-icon-file-text2 {\n", | |
" display: inline-block;\n", | |
" vertical-align: middle;\n", | |
" width: 1em;\n", | |
" height: 1.5em !important;\n", | |
" stroke-width: 0;\n", | |
" stroke: currentColor;\n", | |
" fill: currentColor;\n", | |
"}\n", | |
"</style><pre class='xr-text-repr-fallback'><xarray.DataArray 'o2' (lev: 35, y: 180, x: 360)>\n", | |
"dask.array<mul, shape=(35, 180, 360), dtype=float32, chunksize=(35, 180, 360), chunktype=numpy.ndarray>\n", | |
"Coordinates:\n", | |
" * y (y) float64 -89.5 -88.5 -87.5 -86.5 -85.5 ... 86.5 87.5 88.5 89.5\n", | |
" * lev (lev) float64 2.5 10.0 20.0 32.5 ... 5e+03 5.5e+03 6e+03 6.5e+03\n", | |
" * x (x) float64 0.5 1.5 2.5 3.5 4.5 ... 355.5 356.5 357.5 358.5 359.5\n", | |
" time object 1850-01-16 12:00:00\n", | |
" lon (x, y) float64 0.5 0.5 0.5 0.5 0.5 ... 359.5 359.5 359.5 359.5\n", | |
" lat (x, y) float64 -89.5 -88.5 -87.5 -86.5 ... 86.5 87.5 88.5 89.5\n", | |
" member_id <U8 'r1i1p1f1'\n", | |
" depth (lev) float64 -2.5 -10.0 -20.0 -32.5 ... -5.5e+03 -6e+03 -6.5e+03</pre><div class='xr-wrap' style='display:none'><div class='xr-header'><div class='xr-obj-type'>xarray.DataArray</div><div class='xr-array-name'>'o2'</div><ul class='xr-dim-list'><li><span class='xr-has-index'>lev</span>: 35</li><li><span class='xr-has-index'>y</span>: 180</li><li><span class='xr-has-index'>x</span>: 360</li></ul></div><ul class='xr-sections'><li class='xr-section-item'><div class='xr-array-wrap'><input id='section-f698d63f-ce0f-49dc-b5f8-8ea88ee6e1c5' class='xr-array-in' type='checkbox' checked><label for='section-f698d63f-ce0f-49dc-b5f8-8ea88ee6e1c5' title='Show/hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-array-preview xr-preview'><span>dask.array<chunksize=(35, 180, 360), meta=np.ndarray></span></div><div class='xr-array-data'><table>\n", | |
" <tr>\n", | |
" <td>\n", | |
" <table>\n", | |
" <thead>\n", | |
" <tr>\n", | |
" <td> </td>\n", | |
" <th> Array </th>\n", | |
" <th> Chunk </th>\n", | |
" </tr>\n", | |
" </thead>\n", | |
" <tbody>\n", | |
" \n", | |
" <tr>\n", | |
" <th> Bytes </th>\n", | |
" <td> 8.65 MiB </td>\n", | |
" <td> 8.65 MiB </td>\n", | |
" </tr>\n", | |
" \n", | |
" <tr>\n", | |
" <th> Shape </th>\n", | |
" <td> (35, 180, 360) </td>\n", | |
" <td> (35, 180, 360) </td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th> Count </th>\n", | |
" <td> 310 Tasks </td>\n", | |
" <td> 1 Chunks </td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th> Type </th>\n", | |
" <td> float32 </td>\n", | |
" <td> numpy.ndarray </td>\n", | |
" </tr>\n", | |
" </tbody>\n", | |
" </table>\n", | |
" </td>\n", | |
" <td>\n", | |
" <svg width=\"202\" height=\"132\" style=\"stroke:rgb(0,0,0);stroke-width:1\" >\n", | |
"\n", | |
" <!-- Horizontal lines -->\n", | |
" <line x1=\"10\" y1=\"0\" x2=\"32\" y2=\"22\" style=\"stroke-width:2\" />\n", | |
" <line x1=\"10\" y1=\"60\" x2=\"32\" y2=\"82\" style=\"stroke-width:2\" />\n", | |
"\n", | |
" <!-- Vertical lines -->\n", | |
" <line x1=\"10\" y1=\"0\" x2=\"10\" y2=\"60\" style=\"stroke-width:2\" />\n", | |
" <line x1=\"32\" y1=\"22\" x2=\"32\" y2=\"82\" style=\"stroke-width:2\" />\n", | |
"\n", | |
" <!-- Colored Rectangle -->\n", | |
" <polygon points=\"10.0,0.0 32.61185727002872,22.611857270028718 32.61185727002872,82.61185727002872 10.0,60.0\" style=\"fill:#ECB172A0;stroke-width:0\"/>\n", | |
"\n", | |
" <!-- Horizontal lines -->\n", | |
" <line x1=\"10\" y1=\"0\" x2=\"130\" y2=\"0\" style=\"stroke-width:2\" />\n", | |
" <line x1=\"32\" y1=\"22\" x2=\"152\" y2=\"22\" style=\"stroke-width:2\" />\n", | |
"\n", | |
" <!-- Vertical lines -->\n", | |
" <line x1=\"10\" y1=\"0\" x2=\"32\" y2=\"22\" style=\"stroke-width:2\" />\n", | |
" <line x1=\"130\" y1=\"0\" x2=\"152\" y2=\"22\" style=\"stroke-width:2\" />\n", | |
"\n", | |
" <!-- Colored Rectangle -->\n", | |
" <polygon points=\"10.0,0.0 130.0,0.0 152.6118572700287,22.611857270028718 32.61185727002872,22.611857270028718\" style=\"fill:#ECB172A0;stroke-width:0\"/>\n", | |
"\n", | |
" <!-- Horizontal lines -->\n", | |
" <line x1=\"32\" y1=\"22\" x2=\"152\" y2=\"22\" style=\"stroke-width:2\" />\n", | |
" <line x1=\"32\" y1=\"82\" x2=\"152\" y2=\"82\" style=\"stroke-width:2\" />\n", | |
"\n", | |
" <!-- Vertical lines -->\n", | |
" <line x1=\"32\" y1=\"22\" x2=\"32\" y2=\"82\" style=\"stroke-width:2\" />\n", | |
" <line x1=\"152\" y1=\"22\" x2=\"152\" y2=\"82\" style=\"stroke-width:2\" />\n", | |
"\n", | |
" <!-- Colored Rectangle -->\n", | |
" <polygon points=\"32.61185727002872,22.611857270028718 152.61185727002874,22.611857270028718 152.61185727002874,82.61185727002872 32.61185727002872,82.61185727002872\" style=\"fill:#ECB172A0;stroke-width:0\"/>\n", | |
"\n", | |
" <!-- Text -->\n", | |
" <text x=\"92.611857\" y=\"102.611857\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" >360</text>\n", | |
" <text x=\"172.611857\" y=\"52.611857\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" transform=\"rotate(-90,172.611857,52.611857)\">180</text>\n", | |
" <text x=\"11.305929\" y=\"91.305929\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" transform=\"rotate(45,11.305929,91.305929)\">35</text>\n", | |
"</svg>\n", | |
" </td>\n", | |
" </tr>\n", | |
"</table></div></div></li><li class='xr-section-item'><input id='section-14379e3d-3a69-4f02-892d-a482b330b981' class='xr-section-summary-in' type='checkbox' checked><label for='section-14379e3d-3a69-4f02-892d-a482b330b981' class='xr-section-summary' >Coordinates: <span>(8)</span></label><div class='xr-section-inline-details'></div><div class='xr-section-details'><ul class='xr-var-list'><li class='xr-var-item'><div class='xr-var-name'><span class='xr-has-index'>y</span></div><div class='xr-var-dims'>(y)</div><div class='xr-var-dtype'>float64</div><div class='xr-var-preview xr-preview'>-89.5 -88.5 -87.5 ... 88.5 89.5</div><input id='attrs-3fa139d9-d263-4944-a381-d718890a038c' class='xr-var-attrs-in' type='checkbox' ><label for='attrs-3fa139d9-d263-4944-a381-d718890a038c' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-9422514c-2063-47e1-b162-83e7ddc73289' class='xr-var-data-in' type='checkbox'><label for='data-9422514c-2063-47e1-b162-83e7ddc73289' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'><dt><span>axis :</span></dt><dd>Y</dd><dt><span>bounds :</span></dt><dd>lat_bnds</dd><dt><span>cell_methods :</span></dt><dd>time: point</dd><dt><span>long_name :</span></dt><dd>latitude</dd><dt><span>standard_name :</span></dt><dd>latitude</dd><dt><span>units :</span></dt><dd>degrees_north</dd></dl></div><div class='xr-var-data'><pre>array([-89.5, -88.5, -87.5, -86.5, -85.5, -84.5, -83.5, -82.5, -81.5, -80.5,\n", | |
" -79.5, -78.5, -77.5, -76.5, -75.5, -74.5, -73.5, -72.5, -71.5, -70.5,\n", | |
" -69.5, -68.5, -67.5, -66.5, -65.5, -64.5, -63.5, -62.5, -61.5, -60.5,\n", | |
" -59.5, -58.5, -57.5, -56.5, -55.5, -54.5, -53.5, -52.5, -51.5, -50.5,\n", | |
" -49.5, -48.5, -47.5, -46.5, -45.5, -44.5, -43.5, -42.5, -41.5, -40.5,\n", | |
" -39.5, -38.5, -37.5, -36.5, -35.5, -34.5, -33.5, -32.5, -31.5, -30.5,\n", | |
" -29.5, -28.5, -27.5, -26.5, -25.5, -24.5, -23.5, -22.5, -21.5, -20.5,\n", | |
" -19.5, -18.5, -17.5, -16.5, -15.5, -14.5, -13.5, -12.5, -11.5, -10.5,\n", | |
" -9.5, -8.5, -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5,\n", | |
" 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5, 9.5,\n", | |
" 10.5, 11.5, 12.5, 13.5, 14.5, 15.5, 16.5, 17.5, 18.5, 19.5,\n", | |
" 20.5, 21.5, 22.5, 23.5, 24.5, 25.5, 26.5, 27.5, 28.5, 29.5,\n", | |
" 30.5, 31.5, 32.5, 33.5, 34.5, 35.5, 36.5, 37.5, 38.5, 39.5,\n", | |
" 40.5, 41.5, 42.5, 43.5, 44.5, 45.5, 46.5, 47.5, 48.5, 49.5,\n", | |
" 50.5, 51.5, 52.5, 53.5, 54.5, 55.5, 56.5, 57.5, 58.5, 59.5,\n", | |
" 60.5, 61.5, 62.5, 63.5, 64.5, 65.5, 66.5, 67.5, 68.5, 69.5,\n", | |
" 70.5, 71.5, 72.5, 73.5, 74.5, 75.5, 76.5, 77.5, 78.5, 79.5,\n", | |
" 80.5, 81.5, 82.5, 83.5, 84.5, 85.5, 86.5, 87.5, 88.5, 89.5])</pre></div></li><li class='xr-var-item'><div class='xr-var-name'><span class='xr-has-index'>lev</span></div><div class='xr-var-dims'>(lev)</div><div class='xr-var-dtype'>float64</div><div class='xr-var-preview xr-preview'>2.5 10.0 20.0 ... 6e+03 6.5e+03</div><input id='attrs-dd449322-c0c0-4bf2-a99e-b820b0881961' class='xr-var-attrs-in' type='checkbox' ><label for='attrs-dd449322-c0c0-4bf2-a99e-b820b0881961' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-12c5762b-d8f9-48a8-b605-9b56c6e4c5d8' class='xr-var-data-in' type='checkbox'><label for='data-12c5762b-d8f9-48a8-b605-9b56c6e4c5d8' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'><dt><span>axis :</span></dt><dd>Z</dd><dt><span>bounds :</span></dt><dd>lev_bnds</dd><dt><span>description :</span></dt><dd>generic ocean model vertical coordinate (nondimensional or dimensional)</dd><dt><span>long_name :</span></dt><dd>ocean model level</dd><dt><span>positive :</span></dt><dd>down</dd><dt><span>units :</span></dt><dd>m</dd></dl></div><div class='xr-var-data'><pre>array([2.5000e+00, 1.0000e+01, 2.0000e+01, 3.2500e+01, 5.1250e+01, 7.5000e+01,\n", | |
" 1.0000e+02, 1.2500e+02, 1.5625e+02, 2.0000e+02, 2.5000e+02, 3.1250e+02,\n", | |
" 4.0000e+02, 5.0000e+02, 6.0000e+02, 7.0000e+02, 8.0000e+02, 9.0000e+02,\n", | |
" 1.0000e+03, 1.1000e+03, 1.2000e+03, 1.3000e+03, 1.4000e+03, 1.5375e+03,\n", | |
" 1.7500e+03, 2.0625e+03, 2.5000e+03, 3.0000e+03, 3.5000e+03, 4.0000e+03,\n", | |
" 4.5000e+03, 5.0000e+03, 5.5000e+03, 6.0000e+03, 6.5000e+03])</pre></div></li><li class='xr-var-item'><div class='xr-var-name'><span class='xr-has-index'>x</span></div><div class='xr-var-dims'>(x)</div><div class='xr-var-dtype'>float64</div><div class='xr-var-preview xr-preview'>0.5 1.5 2.5 ... 357.5 358.5 359.5</div><input id='attrs-8f74c25b-9a1a-4947-ba04-4da88d5c3c74' class='xr-var-attrs-in' type='checkbox' ><label for='attrs-8f74c25b-9a1a-4947-ba04-4da88d5c3c74' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-98ba5614-4fec-42f1-a50e-3cb9f069aed2' class='xr-var-data-in' type='checkbox'><label for='data-98ba5614-4fec-42f1-a50e-3cb9f069aed2' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'><dt><span>axis :</span></dt><dd>X</dd><dt><span>bounds :</span></dt><dd>lon_bnds</dd><dt><span>cell_methods :</span></dt><dd>time: point</dd><dt><span>long_name :</span></dt><dd>longitude</dd><dt><span>standard_name :</span></dt><dd>longitude</dd><dt><span>units :</span></dt><dd>degrees_east</dd></dl></div><div class='xr-var-data'><pre>array([ 0.5, 1.5, 2.5, ..., 357.5, 358.5, 359.5])</pre></div></li><li class='xr-var-item'><div class='xr-var-name'><span>time</span></div><div class='xr-var-dims'>()</div><div class='xr-var-dtype'>object</div><div class='xr-var-preview xr-preview'>1850-01-16 12:00:00</div><input id='attrs-35df4da5-0f8d-4339-96f9-22fee67fc388' class='xr-var-attrs-in' type='checkbox' ><label for='attrs-35df4da5-0f8d-4339-96f9-22fee67fc388' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-085952e0-e911-4907-827a-8f3fc9450ead' class='xr-var-data-in' type='checkbox'><label for='data-085952e0-e911-4907-827a-8f3fc9450ead' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'><dt><span>axis :</span></dt><dd>T</dd><dt><span>bounds :</span></dt><dd>time_bnds</dd><dt><span>calendar_type :</span></dt><dd>noleap</dd><dt><span>description :</span></dt><dd>Temporal mean</dd><dt><span>long_name :</span></dt><dd>time</dd><dt><span>standard_name :</span></dt><dd>time</dd></dl></div><div class='xr-var-data'><pre>array(cftime.DatetimeNoLeap(1850, 1, 16, 12, 0, 0, 0, has_year_zero=True),\n", | |
" dtype=object)</pre></div></li><li class='xr-var-item'><div class='xr-var-name'><span>lon</span></div><div class='xr-var-dims'>(x, y)</div><div class='xr-var-dtype'>float64</div><div class='xr-var-preview xr-preview'>0.5 0.5 0.5 ... 359.5 359.5 359.5</div><input id='attrs-9dcf5aac-c057-4ba1-b627-a4cc8061220a' class='xr-var-attrs-in' type='checkbox' disabled><label for='attrs-9dcf5aac-c057-4ba1-b627-a4cc8061220a' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-c826444b-5dab-4b11-aeab-e7b4f624a8d5' class='xr-var-data-in' type='checkbox'><label for='data-c826444b-5dab-4b11-aeab-e7b4f624a8d5' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'></dl></div><div class='xr-var-data'><pre>array([[ 0.5, 0.5, 0.5, ..., 0.5, 0.5, 0.5],\n", | |
" [ 1.5, 1.5, 1.5, ..., 1.5, 1.5, 1.5],\n", | |
" [ 2.5, 2.5, 2.5, ..., 2.5, 2.5, 2.5],\n", | |
" ...,\n", | |
" [357.5, 357.5, 357.5, ..., 357.5, 357.5, 357.5],\n", | |
" [358.5, 358.5, 358.5, ..., 358.5, 358.5, 358.5],\n", | |
" [359.5, 359.5, 359.5, ..., 359.5, 359.5, 359.5]])</pre></div></li><li class='xr-var-item'><div class='xr-var-name'><span>lat</span></div><div class='xr-var-dims'>(x, y)</div><div class='xr-var-dtype'>float64</div><div class='xr-var-preview xr-preview'>-89.5 -88.5 -87.5 ... 88.5 89.5</div><input id='attrs-38d2bcdb-3bd8-4928-a9fd-7603878301de' class='xr-var-attrs-in' type='checkbox' disabled><label for='attrs-38d2bcdb-3bd8-4928-a9fd-7603878301de' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-e8a1157f-f104-4fc3-8314-6454dc3c755e' class='xr-var-data-in' type='checkbox'><label for='data-e8a1157f-f104-4fc3-8314-6454dc3c755e' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'></dl></div><div class='xr-var-data'><pre>array([[-89.5, -88.5, -87.5, ..., 87.5, 88.5, 89.5],\n", | |
" [-89.5, -88.5, -87.5, ..., 87.5, 88.5, 89.5],\n", | |
" [-89.5, -88.5, -87.5, ..., 87.5, 88.5, 89.5],\n", | |
" ...,\n", | |
" [-89.5, -88.5, -87.5, ..., 87.5, 88.5, 89.5],\n", | |
" [-89.5, -88.5, -87.5, ..., 87.5, 88.5, 89.5],\n", | |
" [-89.5, -88.5, -87.5, ..., 87.5, 88.5, 89.5]])</pre></div></li><li class='xr-var-item'><div class='xr-var-name'><span>member_id</span></div><div class='xr-var-dims'>()</div><div class='xr-var-dtype'><U8</div><div class='xr-var-preview xr-preview'>'r1i1p1f1'</div><input id='attrs-27dcdab8-d36a-462e-a0fe-86c0ec443916' class='xr-var-attrs-in' type='checkbox' disabled><label for='attrs-27dcdab8-d36a-462e-a0fe-86c0ec443916' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-a5e43347-2f41-4d0c-816f-20d0a0bd6618' class='xr-var-data-in' type='checkbox'><label for='data-a5e43347-2f41-4d0c-816f-20d0a0bd6618' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'></dl></div><div class='xr-var-data'><pre>array('r1i1p1f1', dtype='<U8')</pre></div></li><li class='xr-var-item'><div class='xr-var-name'><span>depth</span></div><div class='xr-var-dims'>(lev)</div><div class='xr-var-dtype'>float64</div><div class='xr-var-preview xr-preview'>-2.5 -10.0 ... -6e+03 -6.5e+03</div><input id='attrs-735051b0-95b4-4cc5-8c0e-6216d9eee0e4' class='xr-var-attrs-in' type='checkbox' ><label for='attrs-735051b0-95b4-4cc5-8c0e-6216d9eee0e4' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-5cce55fc-5248-4520-ba0f-148a88de9dc7' class='xr-var-data-in' type='checkbox'><label for='data-5cce55fc-5248-4520-ba0f-148a88de9dc7' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'><dt><span>axis :</span></dt><dd>Z</dd><dt><span>bounds :</span></dt><dd>lev_bnds</dd><dt><span>description :</span></dt><dd>generic ocean model vertical coordinate (nondimensional or dimensional)</dd><dt><span>long_name :</span></dt><dd>ocean model level</dd><dt><span>positive :</span></dt><dd>down</dd><dt><span>units :</span></dt><dd>m</dd></dl></div><div class='xr-var-data'><pre>array([-2.5000e+00, -1.0000e+01, -2.0000e+01, -3.2500e+01, -5.1250e+01,\n", | |
" -7.5000e+01, -1.0000e+02, -1.2500e+02, -1.5625e+02, -2.0000e+02,\n", | |
" -2.5000e+02, -3.1250e+02, -4.0000e+02, -5.0000e+02, -6.0000e+02,\n", | |
" -7.0000e+02, -8.0000e+02, -9.0000e+02, -1.0000e+03, -1.1000e+03,\n", | |
" -1.2000e+03, -1.3000e+03, -1.4000e+03, -1.5375e+03, -1.7500e+03,\n", | |
" -2.0625e+03, -2.5000e+03, -3.0000e+03, -3.5000e+03, -4.0000e+03,\n", | |
" -4.5000e+03, -5.0000e+03, -5.5000e+03, -6.0000e+03, -6.5000e+03])</pre></div></li></ul></div></li><li class='xr-section-item'><input id='section-c52b4e26-d914-4258-b5d9-7e793381bb31' class='xr-section-summary-in' type='checkbox' disabled ><label for='section-c52b4e26-d914-4258-b5d9-7e793381bb31' class='xr-section-summary' title='Expand/collapse section'>Attributes: <span>(0)</span></label><div class='xr-section-inline-details'></div><div class='xr-section-details'><dl class='xr-attrs'></dl></div></li></ul></div></div>" | |
], | |
"text/plain": [ | |
"<xarray.DataArray 'o2' (lev: 35, y: 180, x: 360)>\n", | |
"dask.array<mul, shape=(35, 180, 360), dtype=float32, chunksize=(35, 180, 360), chunktype=numpy.ndarray>\n", | |
"Coordinates:\n", | |
" * y (y) float64 -89.5 -88.5 -87.5 -86.5 -85.5 ... 86.5 87.5 88.5 89.5\n", | |
" * lev (lev) float64 2.5 10.0 20.0 32.5 ... 5e+03 5.5e+03 6e+03 6.5e+03\n", | |
" * x (x) float64 0.5 1.5 2.5 3.5 4.5 ... 355.5 356.5 357.5 358.5 359.5\n", | |
" time object 1850-01-16 12:00:00\n", | |
" lon (x, y) float64 0.5 0.5 0.5 0.5 0.5 ... 359.5 359.5 359.5 359.5\n", | |
" lat (x, y) float64 -89.5 -88.5 -87.5 -86.5 ... 86.5 87.5 88.5 89.5\n", | |
" member_id <U8 'r1i1p1f1'\n", | |
" depth (lev) float64 -2.5 -10.0 -20.0 -32.5 ... -5.5e+03 -6e+03 -6.5e+03" | |
] | |
}, | |
"execution_count": 17, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"# The depth is positive. To avoid an upside down plot create a negative coordinate\n", | |
"ds.coords['depth'] = -ds['lev']\n", | |
"\n", | |
"array = ds.o2.isel(time=0).squeeze()*1e3 #use just one time step and convert units to mmol/L\n", | |
"# array = array.coarsen(x=3, y=3).mean()\n", | |
"array" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 18, | |
"id": "b555b2e9-cc3a-4afb-9e30-d871d1e4b89b", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"# Create the mesh. This is amazingly simple! \n", | |
"# I wonder how to implement actual curvilinear coordinates here, but for now this is sufficient\n", | |
"mesh = array.pyvista.mesh(x=\"x\", y=\"y\", z='depth')" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 25, | |
"id": "5709acc8-811a-4b75-b96f-34378dfac06c", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"# need some topo for reference (this is still pretty janky)\n", | |
"depth_masked = array.depth.where(~np.isnan(array))\n", | |
"bottom_index = depth_masked.fillna(10).argmin('lev').load()\n", | |
"topo = array.depth.isel(lev=bottom_index).reset_coords(drop=True)\n", | |
"depth_relative = (depth_masked + topo).fillna(-1)\n", | |
"topo_mesh = depth_relative.pyvista.mesh(x=\"x\", y=\"y\", z='depth').contour(isosurfaces=[-1])" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 29, | |
"id": "bb833063-2ae8-4e0e-a384-1d13a8f1c073", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"application/vnd.jupyter.widget-view+json": { | |
"model_id": "c2b7d0466769466aa057f401e4559e7f", | |
"version_major": 2, | |
"version_minor": 0 | |
}, | |
"text/plain": [ | |
"ViewInteractiveWidget(height=768, layout=Layout(height='auto', width='100%'), width=1024)" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"pl = pv.Plotter(lighting='three lights')\n", | |
"pl.add_mesh(topo_mesh, color='k')\n", | |
"isovalues = [0.1, 5, 10, 50, 100]\n", | |
"pl.add_mesh(\n", | |
" mesh.contour(isosurfaces=isovalues),\n", | |
" opacity=np.linspace(1,0.4, len(isovalues))\n", | |
")\n", | |
"pl.set_scale(zscale=1/50)\n", | |
"pl.view_xy()\n", | |
"pl.add_axes()\n", | |
"pl.show()" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "5145a444-9e94-4312-b2f3-982168662d55", | |
"metadata": {}, | |
"source": [ | |
"Looks pretty cool, but the topography is weird. " | |
] | |
} | |
], | |
"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.9.13" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 5 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment