Skip to content

Instantly share code, notes, and snippets.

@jbusecke
Last active July 13, 2022 02:08
Show Gist options
  • Save jbusecke/9498cd68bd358084f0d96c9009043f58 to your computer and use it in GitHub Desktop.
Save jbusecke/9498cd68bd358084f0d96c9009043f58 to your computer and use it in GitHub Desktop.
CMIP6 Oxygen Minimum Zones with pyvista-xarray
Display the source blob
Display the rendered blob
Raw
{
"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'>&lt;xarray.DataArray &#x27;o2&#x27; (lev: 35, y: 180, x: 360)&gt;\n",
"dask.array&lt;mul, shape=(35, 180, 360), dtype=float32, chunksize=(35, 180, 360), chunktype=numpy.ndarray&gt;\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 &lt;U8 &#x27;r1i1p1f1&#x27;\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&lt;chunksize=(35, 180, 360), meta=np.ndarray&gt;</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'>&lt;U8</div><div class='xr-var-preview xr-preview'>&#x27;r1i1p1f1&#x27;</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(&#x27;r1i1p1f1&#x27;, dtype=&#x27;&lt;U8&#x27;)</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