Created
September 7, 2021 11:01
-
-
Save epifanio/e9f67d9602d881c97fa297a1157c3312 to your computer and use it in GitHub Desktop.
This file contains 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": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"import numpy as np\n", | |
"import xarray as xr\n", | |
"# from bokeh.embed import json_item\n", | |
"import pandas as pd\n", | |
"# from bokeh.io import push_notebook, show, output_notebook\n", | |
"from bokeh.plotting import figure\n", | |
"from bokeh.models import ColumnDataSource, CustomJS, Select #, Column\n", | |
"from bokeh.models.tools import HoverTool\n", | |
"from bokeh.layouts import layout, column #, row\n", | |
"from bokeh.models.widgets import Panel, Tabs, Div\n", | |
"from json2html import *" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"from bokeh.io import output_notebook, show\n", | |
"from bokeh.resources import INLINE\n", | |
"\n", | |
"output_notebook(INLINE) " | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"def get_plottable_variables(nc_url):\n", | |
" ds = xr.open_dataset(nc_url)\n", | |
" num_dims = len(ds.dims)\n", | |
" if num_dims >= 2:\n", | |
" axis_name = 'x_axis'\n", | |
" else:\n", | |
" axis_name = 'y_axis'\n", | |
" return {axis_name: [i for i in ds if len(ds[i].shape) == num_dims]}\n", | |
"\n", | |
"\n", | |
"def get_nc_data(nc_url, nc_variable=None, resample=None):\n", | |
" ds = xr.open_dataset(nc_url)\n", | |
" data = ds.to_dataframe()\n", | |
" data.replace(9.96921e+36, np.NaN, inplace=True)\n", | |
" if nc_variable:\n", | |
" data = data[nc_variable]\n", | |
" if resample:\n", | |
" data = data.resample(resample).mean()\n", | |
" data = pd.DataFrame(data)\n", | |
" data.dataset_metadata = ''\n", | |
" data.dataset_metadata = ds.attrs\n", | |
" data.dataset_metadata['dimension'] = list(ds.dims)\n", | |
" if nc_variable:\n", | |
" data.variable_metadata = ''\n", | |
" data.variable_metadata = ds[nc_variable].attrs\n", | |
" else:\n", | |
" data.variable_metadata = ''\n", | |
" data.variable_metadata = {i: ds[i].attrs for i in ds}\n", | |
" return data\n", | |
"\n", | |
"\n", | |
"def get_vp_data(nc_url, nc_variable='sal', resample=None, levels=None):\n", | |
" profile = get_nc_data(nc_url, nc_variable=nc_variable)\n", | |
" if not levels:\n", | |
" if len(profile.index.names) == 2:\n", | |
" vertical_level, time_level = profile.index.names\n", | |
" else:\n", | |
" raise ValueError\n", | |
" else:\n", | |
" vertical_level, time_level = levels\n", | |
" df = profile.swaplevel()\n", | |
" profile_dict = {str(v): df.loc[[df.index.get_level_values(0)[i]]].reset_index(level=time_level, drop=True)[nc_variable].values for i, v in enumerate(df.index.unique(level=time_level))}\n", | |
" flat_df = pd.DataFrame.from_dict(profile_dict)\n", | |
" flat_df.index = df.index.unique(level=vertical_level)\n", | |
" flat_df.variable_metadata = \"\"\n", | |
" flat_df.dataset_metadata = \"\"\n", | |
" flat_df.variable_metadata = profile.variable_metadata\n", | |
" flat_df.dataset_metadata = profile.dataset_metadata\n", | |
" if 'featureType' not in flat_df.dataset_metadata:\n", | |
" flat_df.dataset_metadata['featureType'] = ''\n", | |
" flat_df.dataset_metadata['featureType'] = 'profile'\n", | |
" return flat_df\n", | |
"\n", | |
"\n", | |
"def create_ts_plot(data):\n", | |
" data['tooltip'] = [x.strftime(\"%Y-%m-%d %H:%M:%S\") for x in data.index]\n", | |
" source = ColumnDataSource(data)\n", | |
" tools_to_show = \"box_zoom, pan,save, hover, reset, wheel_zoom\"\n", | |
" var_label = '@{'+str(data.columns[0]+'}')\n", | |
" try:\n", | |
" var_tooltip_label = str(data.variable_metadata['long_name'])\n", | |
" except KeyError:\n", | |
" var_tooltip_label = str(data.variable_metadata['standard_name'])\n", | |
" p = figure(toolbar_location=\"above\",\n", | |
" x_axis_type=\"datetime\",\n", | |
" tools=tools_to_show) #\n", | |
" p.sizing_mode = 'stretch_width'\n", | |
" tooltips = [('Time', '@tooltip'),\n", | |
" (var_tooltip_label, var_label)\n", | |
" ]\n", | |
" hover = p.select(dict(type=HoverTool))\n", | |
" hover.formatters = {'tooltip': \"datetime\"}\n", | |
" hover.tooltips = tooltips\n", | |
" p.line(x='time',\n", | |
" y=data.columns[0],\n", | |
" source=source,\n", | |
" color='green',\n", | |
" legend_label=data.columns[0],\n", | |
" )\n", | |
" p.min_border_left = 80\n", | |
" p.min_border_right = 80\n", | |
" return p\n", | |
"\n", | |
"\n", | |
"def create_vp_plot(data):\n", | |
" ds = ColumnDataSource(data)\n", | |
" #tools_to_show = \"box_zoom, pan,save, hover, reset, wheel_zoom\"\n", | |
" var_label = '@{' + str(data.columns[0] + '}')\n", | |
" p = figure(toolbar_location=\"above\",\n", | |
" x_axis_type=\"linear\")\n", | |
" p.sizing_mode = 'stretch_width'\n", | |
" select = Select(title=\"Profile-record:\", options=list(data.columns))\n", | |
" try:\n", | |
" vertical_level, time_level = data.dataset_metadata['dimension']\n", | |
" except KeyError:\n", | |
" vertical_level, time_level = ('obsdepth', 'time')\n", | |
" try:\n", | |
" var_tooltip_label = str(data.variable_metadata['long_name'])\n", | |
" except KeyError:\n", | |
" var_tooltip_label = str(data.variable_metadata['standard_name'])\n", | |
" hover = HoverTool(tooltips=[(\"Depth\", \"@\"+vertical_level),\n", | |
" (var_tooltip_label, '@{' + var_label + '}')])\n", | |
"\n", | |
" p.add_tools(hover)\n", | |
" p.y_range.flipped = True\n", | |
" line_renderer = p.line(data.columns[0],\n", | |
" vertical_level,\n", | |
" source=ds,\n", | |
" color='green',\n", | |
" )\n", | |
"\n", | |
" handler = CustomJS(args=dict(line_renderer=line_renderer),\n", | |
" code=\"\"\"\n", | |
" line_renderer.glyph.x = {field: cb_obj.value}; \n", | |
" \"\"\")\n", | |
" select.js_on_change('value', handler)\n", | |
" p.min_border_left = 80\n", | |
" p.min_border_right = 80\n", | |
" return column(select, p, sizing_mode=\"stretch_width\")\n", | |
"\n", | |
"\n", | |
"def create_page(data):\n", | |
" if data.dataset_metadata['featureType'] == 'timeSeries':\n", | |
" plot = create_ts_plot(data)\n", | |
" if data.dataset_metadata['featureType'] == 'profile':\n", | |
" plot = create_vp_plot(data)\n", | |
" try:\n", | |
" title = data.variable_metadata['long_name']\n", | |
" except KeyError:\n", | |
" title = data.variable_metadata['standard_name']\n", | |
" # summary = data.dataset_metadata['summary']\n", | |
" dataset_metadata = json2html.convert(json=data.dataset_metadata,\n", | |
" table_attributes=\"id=\\\"dataset-metadata\\\" \")\n", | |
" variable_metadata = json2html.convert(json=data.variable_metadata,\n", | |
" table_attributes=\"id=\\\"variable-metadata\\\" class=\\\"table table-bordered table-hover\\\"\")\n", | |
" title_div = Div(text=\"\"\"<h1><b>{title}</b></h1>\"\"\".format(title=title))\n", | |
"\n", | |
" dataset_metadata_div = Div(text=\"\"\"{dataset_metadata}\"\"\".format(dataset_metadata=dataset_metadata))\n", | |
"\n", | |
" variable_metadata_div = Div(text=\"\"\"<p>{variable_metadata}</p>\"\"\".format(variable_metadata=variable_metadata))\n", | |
"\n", | |
" metadata_layout = layout([\n", | |
" [title_div],\n", | |
" [variable_metadata_div, dataset_metadata_div],\n", | |
" ], sizing_mode='stretch_width')\n", | |
" tab1 = Panel(child=plot, title=\"Plot\")\n", | |
" tab2 = Panel(child=metadata_layout, title=\"Metadata\")\n", | |
" tabs = Tabs(tabs=[tab1, tab2])\n", | |
" return tabs" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"ts_url = 'https://hyrax.epinux.com/opendap/local_data/SN99938.nc'\n", | |
"vp_url = 'https://hyrax.epinux.com/opendap/local_data/ctdiaoos_gi2007_2009.nc'" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"# Vertical profile\n", | |
"vp_variable = get_plottable_variables(vp_url)\n", | |
"vp_data = get_vp_data(vp_url, vp_variable['x_axis'][0])\n", | |
"vp_plot = create_page(vp_data)\n", | |
"show(vp_plot)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"# Time Series profile\n", | |
"ts_variable = get_plottable_variables(ts_url)\n", | |
"ts_data = get_nc_data(ts_url, ts_variable['y_axis'][0])\n", | |
"ts_plot = create_page(ts_data)\n", | |
"show(ts_plot)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"ts_url = 'https://thredds.met.no/thredds/dodsC/arcticdata/obsSynop/01205'" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"# Time Series profile\n", | |
"ts_variable = get_plottable_variables(ts_url)\n", | |
"ts_data = get_nc_data(ts_url, ts_variable['y_axis'][0])\n", | |
"ts_plot = create_page(ts_data)\n", | |
"show(ts_plot)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"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.5" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 4 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment