Skip to content

Instantly share code, notes, and snippets.

@acrosby
Created May 23, 2022 16:47
Show Gist options
  • Save acrosby/951a87443d706effb456a1d51c791987 to your computer and use it in GitHub Desktop.
Save acrosby/951a87443d706effb456a1d51c791987 to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"id": "7ebf967a-12ab-4662-a814-2a63dfebf08d",
"metadata": {},
"outputs": [],
"source": [
"import sys\n",
"import owi_map\n",
"import pandas as pd\n",
"import numpy as np\n",
"import owi_miscread\n",
"import owi_spectra\n",
"import owi_conversions\n",
"\n",
"import xarray as xr\n",
"import unipost\n",
"import os\n",
"import glob\n",
"\n",
"import datashader\n",
"from datetime import datetime\n",
"import datashader as ds\n",
"import datashader.transfer_functions as tf\n",
"import datashader.utils as du\n",
"\n",
"import rasterio\n",
"from rasterio.transform import from_origin"
]
},
{
"cell_type": "markdown",
"id": "0feeb595-c5a4-4c64-9e87-3e5831d61f57",
"metadata": {},
"source": [
"## Read ADCIRC and put on grid"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "46330f73-93ca-4ad1-af40-afec5c740590",
"metadata": {},
"outputs": [],
"source": [
"def read_adcirc(input, var, lon_name=\"x\", lat_name=\"y\", cell_name=\"element\",\n",
" drop=[\"nbvv\", \"nvell\", \"nvel\", \"nbdv\", \"nvdll\", \"neta\", \"max_nvell\", \"ibtype\"]):\n",
" \"\"\"Read ADCIRC netCDF outputs\n",
"\n",
" Args:\n",
" input (str): Input ADCIRC netCDF file path\n",
" var (str): NetCDF Variable name\n",
" lon_name (optional, str): Default \"x\"\n",
" lat_name (optional, str): Default \"y\"\n",
" cell_name (optional, str): Default \"element\"\n",
"\n",
" Returns:\n",
" da: xr.DataArray of parameter specified by `var`\n",
" lat: Array of node latitudes\n",
" lon: Array of node longitudes\n",
" faces: 2-D Array of cell topology\n",
"\n",
" Examples:\n",
" >>>\n",
" \"\"\"\n",
" ds = xr.open_dataset(input, drop_variables=drop)\n",
" da = ds[var]\n",
"\n",
" # zminf, zmaxf = np.min(zeta), np.max(zeta)\n",
" return da, da[lat_name].values, da[lon_name].values, ds[cell_name].values\n",
"\n",
"\n",
"def datashader_mesh(nodes, tris, mesh=None, nx:int=100, ny:int=100, bounds=None):\n",
" \"\"\"Create datashader object to rasterize the triangular mesh\n",
"\n",
" Args:\n",
" nodes (pandas.DataFrame): DataFrame with cols (x, y, z)\n",
" tris (pandas.DataFrame): DataFrame with cols [v0, v1, v2] specifying the cell topology\n",
" mesh (optional, datashader.utils.Mesh): Datashader mesh object already constructed (save time instead of recreating the mesh)\n",
"\n",
" Returns:\n",
" sd: Datashader object with rasterized representaion of triangular mesh\n",
"\n",
" Examples:\n",
" >>>\n",
" \"\"\"\n",
" bounds = np.asarray(bounds)\n",
" if bounds is None:\n",
" cvs = ds.Canvas(plot_height=ny, plot_width=nx)\n",
" else:\n",
" cvs = ds.Canvas(plot_height=ny, plot_width=nx,\n",
" x_range=bounds[:2], y_range=bounds[2:])\n",
" agg = cvs.trimesh(nodes, tris, mesh=mesh, interp=True)\n",
" return agg\n",
"\n",
"\n",
"def create_mesh(lon, lat, faces, data=None):\n",
" \"\"\"Create inputs that datashader expects for triangulations\n",
"\n",
" Args:\n",
" lon: Iterable or array with 1-D representation of node lon\n",
" lat: Iterable or array with 1-D representation of node lat\n",
" faces: 2-D array of node indices representing cell topology\n",
" data (optional, xarray.DataArray): DataArray for the parameter in netCDF file\n",
"\n",
" Returns:\n",
" tuple: nodes, tris, mesh\n",
"\n",
" Examples:\n",
" >>>\n",
" \"\"\"\n",
" if data is None:\n",
" data = np.arange(lon.shape[0])\n",
" nodes = pd.DataFrame(zip(lon, lat, data), columns=['x', 'y', 'z'], dtype=float)\n",
" tris = pd.DataFrame(faces, columns=['v0', 'v1', 'v2'], dtype=int) - 1\n",
" mesh = du.mesh(nodes, tris)\n",
" return nodes, tris, mesh\n",
"\n",
"\n",
"def adcirc_to_datashader(da, lat, lon, cells, nx, ny, extents=None):\n",
" \"\"\"Convert adcirc output and coord arrays to datashader object\n",
" \"\"\"\n",
" nodes, tris, mesh = create_mesh(lon, lat, cells, data=da.values)\n",
" ds = datashader_mesh(nodes, tris, mesh=mesh, nx=nx, ny=ny, bounds=extents)\n",
" return ds\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "893eb011-6bc7-4350-ac3b-8d7b01f20716",
"metadata": {},
"outputs": [],
"source": [
"adcirc = read_adcirc(\"../ADCIRC/202204160000/fort.64.nc\", [\"u-vel\", \"v-vel\"])\n",
"adcirc[0][\"zeta\"] = read_adcirc(\"../ADCIRC/202204160000/fort.63.nc\", \"zeta\")[0]"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "baf722ab-bb70-4d49-8a6c-1c5e9d599c88",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"(112.5001103165, 118.26372077849999, -23.769922581800003, -18.5122054804)\n"
]
}
],
"source": [
"nx = 250\n",
"ny = 250\n",
"extents=(adcirc[2].min(), # Lon min\n",
" adcirc[2].max(), # Lon max\n",
" adcirc[1].min(), # Lat min\n",
" adcirc[1].max()) # Lat max\n",
"print(extents)"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "4171baf1-56c6-44ea-866b-47eac39c67ae",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"params = (\"zeta\", \"u-vel\", \"v-vel\")\n",
"\n",
"adcirc0 = adcirc[0]\n",
"outputs = []\n",
"for t in adcirc0.time:\n",
" for param in params:\n",
" gridparam = adcirc_to_datashader(adcirc0[param].sel(time=t), \n",
" *adcirc[1:], \n",
" nx=int(nx), ny=int(ny),\n",
" extents=extents\n",
" )\n",
" outputs.append(gridparam)\n",
"\n",
"pgrids = xr.Dataset({\"time\": adcirc0.time})\n",
"nparam = len(params)\n",
"for i, param in enumerate(params):\n",
" pgrids[param] = xr.concat(outputs[i::nparam], dim=\"time\")\n",
"pgrids = pgrids.rename({\"x\": \"lon\", \"y\": \"lat\",})"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "50fd993e-3994-4e39-a637-9f1f18630aa8",
"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;\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.Dataset&gt;\n",
"Dimensions: (time: 72, lon: 250, lat: 250)\n",
"Coordinates:\n",
" * time (time) datetime64[ns] 2022-04-16T01:00:00 ... 2022-04-19\n",
" * lon (lon) float64 112.5 112.5 112.6 112.6 ... 118.2 118.2 118.2 118.3\n",
" * lat (lat) float64 -23.76 -23.74 -23.72 -23.7 ... -18.56 -18.54 -18.52\n",
"Data variables:\n",
" zeta (time, lat, lon) float64 nan nan nan nan nan ... nan nan nan nan\n",
" u-vel (time, lat, lon) float64 nan nan nan nan nan ... nan nan nan nan\n",
" v-vel (time, lat, lon) float64 nan nan nan nan nan ... nan nan nan nan</pre><div class='xr-wrap' hidden><div class='xr-header'><div class='xr-obj-type'>xarray.Dataset</div></div><ul class='xr-sections'><li class='xr-section-item'><input id='section-0f8d1682-a26e-4498-bde0-7da9c4c56345' class='xr-section-summary-in' type='checkbox' disabled ><label for='section-0f8d1682-a26e-4498-bde0-7da9c4c56345' class='xr-section-summary' title='Expand/collapse section'>Dimensions:</label><div class='xr-section-inline-details'><ul class='xr-dim-list'><li><span class='xr-has-index'>time</span>: 72</li><li><span class='xr-has-index'>lon</span>: 250</li><li><span class='xr-has-index'>lat</span>: 250</li></ul></div><div class='xr-section-details'></div></li><li class='xr-section-item'><input id='section-35cd87cc-a08e-4cfb-ba37-efa859b07df6' class='xr-section-summary-in' type='checkbox' checked><label for='section-35cd87cc-a08e-4cfb-ba37-efa859b07df6' class='xr-section-summary' >Coordinates: <span>(3)</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'>time</span></div><div class='xr-var-dims'>(time)</div><div class='xr-var-dtype'>datetime64[ns]</div><div class='xr-var-preview xr-preview'>2022-04-16T01:00:00 ... 2022-04-19</div><input id='attrs-4cae3a25-2f48-4dde-9bc2-00748515f5f4' class='xr-var-attrs-in' type='checkbox' disabled><label for='attrs-4cae3a25-2f48-4dde-9bc2-00748515f5f4' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-b15d0fdf-e586-400f-8d23-c5818d348024' class='xr-var-data-in' type='checkbox'><label for='data-b15d0fdf-e586-400f-8d23-c5818d348024' 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;2022-04-16T01:00:00.000000000&#x27;, &#x27;2022-04-16T02:00:00.000000000&#x27;,\n",
" &#x27;2022-04-16T03:00:00.000000000&#x27;, &#x27;2022-04-16T04:00:00.000000000&#x27;,\n",
" &#x27;2022-04-16T05:00:00.000000000&#x27;, &#x27;2022-04-16T06:00:00.000000000&#x27;,\n",
" &#x27;2022-04-16T07:00:00.000000000&#x27;, &#x27;2022-04-16T08:00:00.000000000&#x27;,\n",
" &#x27;2022-04-16T09:00:00.000000000&#x27;, &#x27;2022-04-16T10:00:00.000000000&#x27;,\n",
" &#x27;2022-04-16T11:00:00.000000000&#x27;, &#x27;2022-04-16T12:00:00.000000000&#x27;,\n",
" &#x27;2022-04-16T13:00:00.000000000&#x27;, &#x27;2022-04-16T14:00:00.000000000&#x27;,\n",
" &#x27;2022-04-16T15:00:00.000000000&#x27;, &#x27;2022-04-16T16:00:00.000000000&#x27;,\n",
" &#x27;2022-04-16T17:00:00.000000000&#x27;, &#x27;2022-04-16T18:00:00.000000000&#x27;,\n",
" &#x27;2022-04-16T19:00:00.000000000&#x27;, &#x27;2022-04-16T20:00:00.000000000&#x27;,\n",
" &#x27;2022-04-16T21:00:00.000000000&#x27;, &#x27;2022-04-16T22:00:00.000000000&#x27;,\n",
" &#x27;2022-04-16T23:00:00.000000000&#x27;, &#x27;2022-04-17T00:00:00.000000000&#x27;,\n",
" &#x27;2022-04-17T01:00:00.000000000&#x27;, &#x27;2022-04-17T02:00:00.000000000&#x27;,\n",
" &#x27;2022-04-17T03:00:00.000000000&#x27;, &#x27;2022-04-17T04:00:00.000000000&#x27;,\n",
" &#x27;2022-04-17T05:00:00.000000000&#x27;, &#x27;2022-04-17T06:00:00.000000000&#x27;,\n",
" &#x27;2022-04-17T07:00:00.000000000&#x27;, &#x27;2022-04-17T08:00:00.000000000&#x27;,\n",
" &#x27;2022-04-17T09:00:00.000000000&#x27;, &#x27;2022-04-17T10:00:00.000000000&#x27;,\n",
" &#x27;2022-04-17T11:00:00.000000000&#x27;, &#x27;2022-04-17T12:00:00.000000000&#x27;,\n",
" &#x27;2022-04-17T13:00:00.000000000&#x27;, &#x27;2022-04-17T14:00:00.000000000&#x27;,\n",
" &#x27;2022-04-17T15:00:00.000000000&#x27;, &#x27;2022-04-17T16:00:00.000000000&#x27;,\n",
" &#x27;2022-04-17T17:00:00.000000000&#x27;, &#x27;2022-04-17T18:00:00.000000000&#x27;,\n",
" &#x27;2022-04-17T19:00:00.000000000&#x27;, &#x27;2022-04-17T20:00:00.000000000&#x27;,\n",
" &#x27;2022-04-17T21:00:00.000000000&#x27;, &#x27;2022-04-17T22:00:00.000000000&#x27;,\n",
" &#x27;2022-04-17T23:00:00.000000000&#x27;, &#x27;2022-04-18T00:00:00.000000000&#x27;,\n",
" &#x27;2022-04-18T01:00:00.000000000&#x27;, &#x27;2022-04-18T02:00:00.000000000&#x27;,\n",
" &#x27;2022-04-18T03:00:00.000000000&#x27;, &#x27;2022-04-18T04:00:00.000000000&#x27;,\n",
" &#x27;2022-04-18T05:00:00.000000000&#x27;, &#x27;2022-04-18T06:00:00.000000000&#x27;,\n",
" &#x27;2022-04-18T07:00:00.000000000&#x27;, &#x27;2022-04-18T08:00:00.000000000&#x27;,\n",
" &#x27;2022-04-18T09:00:00.000000000&#x27;, &#x27;2022-04-18T10:00:00.000000000&#x27;,\n",
" &#x27;2022-04-18T11:00:00.000000000&#x27;, &#x27;2022-04-18T12:00:00.000000000&#x27;,\n",
" &#x27;2022-04-18T13:00:00.000000000&#x27;, &#x27;2022-04-18T14:00:00.000000000&#x27;,\n",
" &#x27;2022-04-18T15:00:00.000000000&#x27;, &#x27;2022-04-18T16:00:00.000000000&#x27;,\n",
" &#x27;2022-04-18T17:00:00.000000000&#x27;, &#x27;2022-04-18T18:00:00.000000000&#x27;,\n",
" &#x27;2022-04-18T19:00:00.000000000&#x27;, &#x27;2022-04-18T20:00:00.000000000&#x27;,\n",
" &#x27;2022-04-18T21:00:00.000000000&#x27;, &#x27;2022-04-18T22:00:00.000000000&#x27;,\n",
" &#x27;2022-04-18T23:00:00.000000000&#x27;, &#x27;2022-04-19T00:00:00.000000000&#x27;],\n",
" dtype=&#x27;datetime64[ns]&#x27;)</pre></div></li><li class='xr-var-item'><div class='xr-var-name'><span class='xr-has-index'>lon</span></div><div class='xr-var-dims'>(lon)</div><div class='xr-var-dtype'>float64</div><div class='xr-var-preview xr-preview'>112.5 112.5 112.6 ... 118.2 118.3</div><input id='attrs-5c646cdd-df48-4c69-9091-fdff32eff81d' class='xr-var-attrs-in' type='checkbox' disabled><label for='attrs-5c646cdd-df48-4c69-9091-fdff32eff81d' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-b50d33b0-e2a3-4198-9786-6b5a66717661' class='xr-var-data-in' type='checkbox'><label for='data-b50d33b0-e2a3-4198-9786-6b5a66717661' 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([112.511638, 112.534692, 112.557746, ..., 118.206085, 118.229139,\n",
" 118.252194])</pre></div></li><li class='xr-var-item'><div class='xr-var-name'><span class='xr-has-index'>lat</span></div><div class='xr-var-dims'>(lat)</div><div class='xr-var-dtype'>float64</div><div class='xr-var-preview xr-preview'>-23.76 -23.74 ... -18.54 -18.52</div><input id='attrs-7dbae968-95f2-436f-ae09-e0c4c79c3ee4' class='xr-var-attrs-in' type='checkbox' disabled><label for='attrs-7dbae968-95f2-436f-ae09-e0c4c79c3ee4' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-dea3d62c-4b77-40be-8271-22141a3e8483' class='xr-var-data-in' type='checkbox'><label for='data-dea3d62c-4b77-40be-8271-22141a3e8483' 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([-23.759407, -23.738376, -23.717345, ..., -18.564783, -18.543752,\n",
" -18.522721])</pre></div></li></ul></div></li><li class='xr-section-item'><input id='section-2ab28d1d-55fc-4be3-9fe0-00b903fb8f6e' class='xr-section-summary-in' type='checkbox' checked><label for='section-2ab28d1d-55fc-4be3-9fe0-00b903fb8f6e' class='xr-section-summary' >Data variables: <span>(3)</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>zeta</span></div><div class='xr-var-dims'>(time, lat, lon)</div><div class='xr-var-dtype'>float64</div><div class='xr-var-preview xr-preview'>nan nan nan nan ... nan nan nan nan</div><input id='attrs-7d6adb1f-7b49-4f8c-8599-772ce8c1959f' class='xr-var-attrs-in' type='checkbox' disabled><label for='attrs-7d6adb1f-7b49-4f8c-8599-772ce8c1959f' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-ba792d27-acd5-4c83-8e4e-af03ac2e73cd' class='xr-var-data-in' type='checkbox'><label for='data-ba792d27-acd5-4c83-8e4e-af03ac2e73cd' 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([[[nan, nan, nan, ..., nan, nan, nan],\n",
" [nan, nan, nan, ..., nan, nan, nan],\n",
" [nan, nan, nan, ..., nan, nan, nan],\n",
" ...,\n",
" [nan, nan, nan, ..., nan, nan, nan],\n",
" [nan, nan, nan, ..., nan, nan, nan],\n",
" [nan, nan, nan, ..., nan, nan, nan]],\n",
"\n",
" [[nan, nan, nan, ..., nan, nan, nan],\n",
" [nan, nan, nan, ..., nan, nan, nan],\n",
" [nan, nan, nan, ..., nan, nan, nan],\n",
" ...,\n",
" [nan, nan, nan, ..., nan, nan, nan],\n",
" [nan, nan, nan, ..., nan, nan, nan],\n",
" [nan, nan, nan, ..., nan, nan, nan]],\n",
"\n",
" [[nan, nan, nan, ..., nan, nan, nan],\n",
" [nan, nan, nan, ..., nan, nan, nan],\n",
" [nan, nan, nan, ..., nan, nan, nan],\n",
" ...,\n",
"...\n",
" ...,\n",
" [nan, nan, nan, ..., nan, nan, nan],\n",
" [nan, nan, nan, ..., nan, nan, nan],\n",
" [nan, nan, nan, ..., nan, nan, nan]],\n",
"\n",
" [[nan, nan, nan, ..., nan, nan, nan],\n",
" [nan, nan, nan, ..., nan, nan, nan],\n",
" [nan, nan, nan, ..., nan, nan, nan],\n",
" ...,\n",
" [nan, nan, nan, ..., nan, nan, nan],\n",
" [nan, nan, nan, ..., nan, nan, nan],\n",
" [nan, nan, nan, ..., nan, nan, nan]],\n",
"\n",
" [[nan, nan, nan, ..., nan, nan, nan],\n",
" [nan, nan, nan, ..., nan, nan, nan],\n",
" [nan, nan, nan, ..., nan, nan, nan],\n",
" ...,\n",
" [nan, nan, nan, ..., nan, nan, nan],\n",
" [nan, nan, nan, ..., nan, nan, nan],\n",
" [nan, nan, nan, ..., nan, nan, nan]]])</pre></div></li><li class='xr-var-item'><div class='xr-var-name'><span>u-vel</span></div><div class='xr-var-dims'>(time, lat, lon)</div><div class='xr-var-dtype'>float64</div><div class='xr-var-preview xr-preview'>nan nan nan nan ... nan nan nan nan</div><input id='attrs-4972621e-1294-4158-9b5a-d3baf01a735e' class='xr-var-attrs-in' type='checkbox' disabled><label for='attrs-4972621e-1294-4158-9b5a-d3baf01a735e' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-eb7fdc56-693c-46a3-ba27-f71ae12f4064' class='xr-var-data-in' type='checkbox'><label for='data-eb7fdc56-693c-46a3-ba27-f71ae12f4064' 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([[[nan, nan, nan, ..., nan, nan, nan],\n",
" [nan, nan, nan, ..., nan, nan, nan],\n",
" [nan, nan, nan, ..., nan, nan, nan],\n",
" ...,\n",
" [nan, nan, nan, ..., nan, nan, nan],\n",
" [nan, nan, nan, ..., nan, nan, nan],\n",
" [nan, nan, nan, ..., nan, nan, nan]],\n",
"\n",
" [[nan, nan, nan, ..., nan, nan, nan],\n",
" [nan, nan, nan, ..., nan, nan, nan],\n",
" [nan, nan, nan, ..., nan, nan, nan],\n",
" ...,\n",
" [nan, nan, nan, ..., nan, nan, nan],\n",
" [nan, nan, nan, ..., nan, nan, nan],\n",
" [nan, nan, nan, ..., nan, nan, nan]],\n",
"\n",
" [[nan, nan, nan, ..., nan, nan, nan],\n",
" [nan, nan, nan, ..., nan, nan, nan],\n",
" [nan, nan, nan, ..., nan, nan, nan],\n",
" ...,\n",
"...\n",
" ...,\n",
" [nan, nan, nan, ..., nan, nan, nan],\n",
" [nan, nan, nan, ..., nan, nan, nan],\n",
" [nan, nan, nan, ..., nan, nan, nan]],\n",
"\n",
" [[nan, nan, nan, ..., nan, nan, nan],\n",
" [nan, nan, nan, ..., nan, nan, nan],\n",
" [nan, nan, nan, ..., nan, nan, nan],\n",
" ...,\n",
" [nan, nan, nan, ..., nan, nan, nan],\n",
" [nan, nan, nan, ..., nan, nan, nan],\n",
" [nan, nan, nan, ..., nan, nan, nan]],\n",
"\n",
" [[nan, nan, nan, ..., nan, nan, nan],\n",
" [nan, nan, nan, ..., nan, nan, nan],\n",
" [nan, nan, nan, ..., nan, nan, nan],\n",
" ...,\n",
" [nan, nan, nan, ..., nan, nan, nan],\n",
" [nan, nan, nan, ..., nan, nan, nan],\n",
" [nan, nan, nan, ..., nan, nan, nan]]])</pre></div></li><li class='xr-var-item'><div class='xr-var-name'><span>v-vel</span></div><div class='xr-var-dims'>(time, lat, lon)</div><div class='xr-var-dtype'>float64</div><div class='xr-var-preview xr-preview'>nan nan nan nan ... nan nan nan nan</div><input id='attrs-57b61bda-e476-4acc-93d8-b7b8bab6012a' class='xr-var-attrs-in' type='checkbox' disabled><label for='attrs-57b61bda-e476-4acc-93d8-b7b8bab6012a' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-bfde4553-ea17-467e-aaf5-6c83b97bcaa5' class='xr-var-data-in' type='checkbox'><label for='data-bfde4553-ea17-467e-aaf5-6c83b97bcaa5' 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([[[nan, nan, nan, ..., nan, nan, nan],\n",
" [nan, nan, nan, ..., nan, nan, nan],\n",
" [nan, nan, nan, ..., nan, nan, nan],\n",
" ...,\n",
" [nan, nan, nan, ..., nan, nan, nan],\n",
" [nan, nan, nan, ..., nan, nan, nan],\n",
" [nan, nan, nan, ..., nan, nan, nan]],\n",
"\n",
" [[nan, nan, nan, ..., nan, nan, nan],\n",
" [nan, nan, nan, ..., nan, nan, nan],\n",
" [nan, nan, nan, ..., nan, nan, nan],\n",
" ...,\n",
" [nan, nan, nan, ..., nan, nan, nan],\n",
" [nan, nan, nan, ..., nan, nan, nan],\n",
" [nan, nan, nan, ..., nan, nan, nan]],\n",
"\n",
" [[nan, nan, nan, ..., nan, nan, nan],\n",
" [nan, nan, nan, ..., nan, nan, nan],\n",
" [nan, nan, nan, ..., nan, nan, nan],\n",
" ...,\n",
"...\n",
" ...,\n",
" [nan, nan, nan, ..., nan, nan, nan],\n",
" [nan, nan, nan, ..., nan, nan, nan],\n",
" [nan, nan, nan, ..., nan, nan, nan]],\n",
"\n",
" [[nan, nan, nan, ..., nan, nan, nan],\n",
" [nan, nan, nan, ..., nan, nan, nan],\n",
" [nan, nan, nan, ..., nan, nan, nan],\n",
" ...,\n",
" [nan, nan, nan, ..., nan, nan, nan],\n",
" [nan, nan, nan, ..., nan, nan, nan],\n",
" [nan, nan, nan, ..., nan, nan, nan]],\n",
"\n",
" [[nan, nan, nan, ..., nan, nan, nan],\n",
" [nan, nan, nan, ..., nan, nan, nan],\n",
" [nan, nan, nan, ..., nan, nan, nan],\n",
" ...,\n",
" [nan, nan, nan, ..., nan, nan, nan],\n",
" [nan, nan, nan, ..., nan, nan, nan],\n",
" [nan, nan, nan, ..., nan, nan, nan]]])</pre></div></li></ul></div></li><li class='xr-section-item'><input id='section-f291db8f-0efb-4214-b013-6860d68f1d9c' class='xr-section-summary-in' type='checkbox' disabled ><label for='section-f291db8f-0efb-4214-b013-6860d68f1d9c' 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.Dataset>\n",
"Dimensions: (time: 72, lon: 250, lat: 250)\n",
"Coordinates:\n",
" * time (time) datetime64[ns] 2022-04-16T01:00:00 ... 2022-04-19\n",
" * lon (lon) float64 112.5 112.5 112.6 112.6 ... 118.2 118.2 118.2 118.3\n",
" * lat (lat) float64 -23.76 -23.74 -23.72 -23.7 ... -18.56 -18.54 -18.52\n",
"Data variables:\n",
" zeta (time, lat, lon) float64 nan nan nan nan nan ... nan nan nan nan\n",
" u-vel (time, lat, lon) float64 nan nan nan nan nan ... nan nan nan nan\n",
" v-vel (time, lat, lon) float64 nan nan nan nan nan ... nan nan nan nan"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"pgrids"
]
},
{
"cell_type": "markdown",
"id": "5996c302-7e5b-4a8c-a3a4-66481efb006c",
"metadata": {},
"source": [
"## Plot with matplotlib and cartopy"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "d98cb94b-ac44-4550-9de4-a2222ea41243",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<cartopy.mpl.geocollection.GeoQuadMesh at 0x7fd3cd92b970>"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"pgrids[\"zeta\"].isel(time=2).unipost.pcolormesh()"
]
},
{
"cell_type": "markdown",
"id": "9c6fe820-5da0-468a-a90c-90c1f71916e5",
"metadata": {},
"source": [
"## Convert grid to GeoTiff with raster.io"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "9ca8710a-9f17-42f3-9eea-1ef023633f60",
"metadata": {},
"outputs": [],
"source": [
"def datashader_to_raster(output, griddata):\n",
" \"\"\"Convert gridded datashader object to regular grid GeoTiff (georeferenced image) raster file\n",
" \"\"\"\n",
" sd = griddata\n",
" ny, nx = sd.shape\n",
" xres = sd.lon[1] - sd.lon[0]\n",
" yres = sd.lat[1] - sd.lat[0]\n",
" transform = from_origin(sd.lon[0] - xres / 2, sd.lat[-1] + yres / 2, xres, yres)\n",
" with rasterio.open(output, 'w', driver='GTiff', height=ny, width=nx,\n",
" count=1, dtype='float64', crs='+proj=latlong',\n",
" transform=transform) as f:\n",
" sd2 = sd.values.ravel()\n",
" sd3 = np.ma.masked_invalid(sd2).filled()\n",
" f.nodata = -99.\n",
" f.write(sd3.reshape((ny, nx))[::-1, :], 1)"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "30e23e73-bf93-489a-95a0-841ac2291286",
"metadata": {},
"outputs": [],
"source": [
"datashader_to_raster(\"/home/alex/Desktop/test.tiff\", pgrids[\"zeta\"].isel(time=2))"
]
},
{
"cell_type": "markdown",
"id": "57467271-8962-45c0-b0cb-1ec887d5eea6",
"metadata": {},
"source": [
"## Using plotly/mapbox for interactive map\n",
"\n",
"You can take a look at my post about plotly/mapbox for some info/tools for creating webmap from python just overlaying the image once the gridded datashader object is projected to webmercator:\n",
"\n",
"[https://acrosby.github.io/python/projecting-plotly-mapbox-rasters.html](https://acrosby.github.io/python/projecting-plotly-mapbox-rasters.html)\n",
"\n",
"You can do something similar with `folium` or `bokeh` as well."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cf919a9a-ebf1-4b64-9613-6750481697f9",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"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.8.8"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment