Skip to content

Instantly share code, notes, and snippets.

@epifanio
Created October 21, 2024 20:52
Show Gist options
  • Save epifanio/7101870f0ffa5e8d9267f7adc247364d to your computer and use it in GitHub Desktop.
Save epifanio/7101870f0ffa5e8d9267f7adc247364d to your computer and use it in GitHub Desktop.
import hvplot.xarray
import xarray as xr
import holoviews as hv
from bokeh.layouts import column
from bokeh.models import Select
from bokeh.io import curdoc
import gc
# hv.extension('bokeh')
def safe_check(var):
try:
ds[var].values
return var
except Exception as e:
# Handle the exception (e.g., log it, return False, etc.)
print(f"Error processing {var}: {e}")
return False
def load_data(url):
try:
del ds
gc.collect()
except UnboundLocalError:
pass
ds = None
try:
# attempt to load the dataset via xarray with decode_times=True
ds = xr.open_dataset(str(url).strip())
except ValueError as e:
# attempt to load the dataset via xarray with decode_times=False
ds = xr.open_dataset(str(url).strip(), decode_times=False)
print(e)
except OSError as e:
print(e)
if ds and not ds.coords:
del ds
gc.collect()
# the following hack is used when the dataset is served as a tabledap via erdap
erdapp_uglyness = list(dict(xr.open_dataset(url).dims).keys())[0]
renamed_vars = {i:i.replace(erdapp_uglyness+".", "") for i in list(xr.open_dataset(url).variables.keys())}
new_nc_url = url+'?'+'time,'+','.join(list(xr.open_dataset(url).variables)).replace(f"{erdapp_uglyness}.", "").replace(f"time,", "")
ds = xr.open_dataset(new_nc_url)
ds = ds.set_coords(f"{erdapp_uglyness}.time")
ds = ds.swap_dims(s=f"time")
ds = ds.set_xindex(f"{erdapp_uglyness}.time")
ds = ds.rename_vars(renamed_vars)
return ds
def update_plot(attr, old, new, var=None, title=None):
print('update plot')
if var is None:
var = new
title = new
if 'featureType' in ds.attrs:
featureType = ds.attrs['featureType'].lower()
elif 'cdm_data_type' in ds[var].attrs:
featureType = ds[var].attrs['cdm_data_type'].lower()
else:
featureType = None
if featureType == 'timeseries':
axis_arguments = {'grid':True, 'title': title, 'responsive': False}
plot_widget = ds[var].where(ds[var] != 9.96921e36).hvplot.line(**axis_arguments)
#return plot_widget
if featureType != "timeseries":
axis_arguments = {'x': ds[var], 'grid':True, 'title': title, 'widget_location': 'bottom', 'responsive': False}
try:
plot_widget = ds[var].where(ds[var] != 9.96921e36).hvplot.line(**axis_arguments)
except TypeError:
axis_arguments = {'grid':True, 'title': title, 'widget_location': 'bottom', 'responsive': False}
plot_widget = ds[var].where(ds[var] != 9.96921e36).hvplot.line(**axis_arguments)
except ValueError:
axis_arguments = {'x': var, 'grid':True, 'title': title, 'widget_location': 'bottom', 'responsive': False}
plot_widget = ds[var].where(ds[var] != 9.96921e36).hvplot.line(**axis_arguments)
#return plot_widget
try:
container.children[1] = hv.render(plot_widget)
except NameError:
return plot_widget
ds = load_data(curdoc().session_context.request.arguments['url'][0].decode('utf-8'))
if ds:
plottable_vars = [j for j in ds if len([value for value in list(ds[j].coords) if value in list(ds.dims)]) >= 1]
plottable_vars = [i for i in plottable_vars if safe_check(i)]
print("plottable_vars:", plottable_vars )
mapping_var_names = {}
for i in plottable_vars:
if int(len(list(ds[i].coords)) != 0):
try:
title = f"{ds[i].attrs['long_name']} [{i}]"
except KeyError:
title = f"{i}"
mapping_var_names[i] = title
select = Select(title="Select a variable:", value=plottable_vars[0], options=plottable_vars)
select.on_change('value', update_plot)
container = column(select, hv.render(update_plot(attr=None, old=None, new=None, var=select.value, title=select.value)))
curdoc().add_root(container)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment