print('Starting app')
import panel as pn
pn.extension()
import holoviews as hv
from holoviews import opts
from holoviews.operation.datashader import datashade
import datashader.reductions as dsr
hv.extension('bokeh')
import geoviews as gv
import cartopy.crs as ccrs
import pandas as pd
import numpy as np
import matplotlib as mpl
import cmocean
from utils.mpl import cmap_to_list
from imports import theme
hv.renderer('bokeh').theme = theme
dims = dict(
nitrate=hv.Dimension('nitrate', label='NO₃', unit='µM'),
depth=hv.Dimension('depth', label='Depth', unit='m', range=(0,300)),
lon=hv.Dimension('lon', label='Longitude', unit='°E'),
lat=hv.Dimension('lat', label='Latitude', unit='°N'),
)
df = pd.read_csv('../data/no3-compilation/database.csv', parse_dates=['date'])
df_single = pd.read_csv('../data/no3-compilation/database-per-stn.csv', parse_dates=['date'])
Map to select points
loc = gv.feature.land * gv.feature.coastline * gv.Points(df_single, ['lon', 'lat'], [])
loc = loc.relabel('Select a region')
selection = hv.streams.Selection1D(source=loc, index=list(range(len(df_single)))) # set default arg
Datashaded nitrate profiles
cmap = cmocean.cm.phase
colors = cmap_to_list(cmap, 12)
# mock points for legend. see http://holoviews.org/user_guide/Large_Data.html, # Multidimensional plots
legend_points = hv.Overlay(
[hv.Scatter([-100, 0], label=str(k+1)).opts(color=v, marker='square', legend_position='right')
for k, v in list(enumerate(colors))])
# mock data to append to streamed dataframe to ensure that all months are represented with same color scaling as in mock legend
months = pd.DataFrame(dict(month=np.arange(12)))
def get_ntr(index):
stations = df_single.iloc[index].station
return df.loc[df.station.isin(stations)]
ntr_toshade = hv.DynamicMap(
lambda index: hv.Scatter(
pd.concat([get_ntr(index), months], sort='False'),
'depth', ['nitrate', 'month']
),
streams=[selection]
)
ntr_shaded = (
datashade(
ntr_toshade,
aggregator=dsr.count_cat('month'), color_key=cmap,
dynamic=True, normalization='eq_hist',
x_sampling=5, y_sampling=0.25
)
* legend_points
).relabel('All selected profiles').redim(**dims)
Monthly averaged nitrate profiles
ntr_avg = hv.DynamicMap(
lambda index: hv.Scatter(
get_ntr(index).groupby(['month', 'depth']).mean(),
'depth', ['nitrate', 'month']
).groupby('month').overlay(),
streams=[selection]
).relabel('Monthly average').redim(**dims)
Define options
options = [
opts.Points(
active_tools=['lasso_select'], tools=['lasso_select', 'box_select'],
projection=ccrs.NorthPolarStereo(),
frame_height=400, aspect=1,
),
opts.Scatter(
invert_axes=True, invert_yaxis=True,
color=hv.Cycle([mpl.colors.to_hex(c) for c in colors]),
width=500, frame_height=400,
),
opts.RGB(
invert_axes=True, invert_yaxis=True,
ylim=(0, None),
width=500, frame_height=400,
),
opts.NdOverlay(legend_position='right', ),
opts.Layout(merge_tools=False),
]
Build app
l = (loc + ntr_shaded + ntr_avg).opts(*options)
app = pn.Row(
loc,
ntr_avg,
ntr_shaded
)
print('Rendering now!')
app.servable()