2/17/2020. https://github.com/emiliom
Goal: Generate a histogram plot that responds dynamically to two panel widgets that select data from a Dataframe: one widget selects a subset of rows ("TROCAS number") and the other the column ("Parameter") to plot. The y and x axes should update dynamically to the selected data's distribution. Ultimately, I'd like to be able to also specify the xmin and xmax values and the number or width of the bins.
Notebook was run on a conda environment created with this environment file.
import pandas as pd
import holoviews as hv
import hvplot.pandas
import panel as pn
hv.extension('bokeh', logo=False)
pn.extension(logo=False)
pn.__version__, hv.__version__, hvplot.__version__
('0.8.0', '1.12.7', '0.5.2')
Also tested with panel versions 0.7.0 and 0.6.2, holoviews version 1.12.5, and hvplot version 0.4.0.
mbdata_df = pd.read_parquet('./data/merged_1minbinned_df.parq', engine='fastparquet')
mbdata_points = hv.Points(mbdata_df, kdims=['longitude', 'latitude'])
mbdata_df.head()
date_time | TROCAS_nbr | TROCAS_nbr_lico | TROCAS_nbr_gps | longitude | latitude | collectiontype_lico | filename_lico | reldirpath_lico | CO2(ppm) | ... | ODO mg/L | pH | Temp °C | Turbidity FNU | Chlorophyll µg/L | TROCAS_nbr_pica | 12CO2 | Delta_Raw_iCO2 | 12CH4 | Delta_iCH4_Raw | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 2014-04-27 19:37:00 | 1 | 1 | 1 | -52.854421 | -1.573241 | mixed | transect27_04_14.txt | Underway Data/T1 Underway data/Licor/all data | 6176.03 | ... | NaN | NaN | NaN | NaN | NaN | None | NaN | NaN | NaN | NaN |
1 | 2014-04-27 19:38:00 | 1 | 1 | 1 | -52.856045 | -1.573726 | mixed | transect27_04_14.txt | Underway Data/T1 Underway data/Licor/all data | 6166.22 | ... | NaN | NaN | NaN | NaN | NaN | None | NaN | NaN | NaN | NaN |
2 | 2014-04-27 19:39:00 | 1 | 1 | 1 | -52.857891 | -1.574407 | mixed | transect27_04_14.txt | Underway Data/T1 Underway data/Licor/all data | 6136.48 | ... | 7.93 | 4.46 | 24.7635 | NaN | NaN | None | NaN | NaN | NaN | NaN |
3 | 2014-04-27 19:40:00 | 1 | 1 | 1 | -52.859618 | -1.574926 | mixed | transect27_04_14.txt | Underway Data/T1 Underway data/Licor/all data | 6126.09 | ... | 3.98 | 6.19 | 29.1415 | NaN | NaN | None | NaN | NaN | NaN | NaN |
4 | 2014-04-27 19:41:00 | 1 | 1 | 1 | -52.861409 | -1.575279 | mixed | transect27_04_14.txt | Underway Data/T1 Underway data/Licor/all data | 6144.64 | ... | 3.81 | 6.29 | 29.1680 | NaN | NaN | None | NaN | NaN | NaN | NaN |
5 rows × 24 columns
A "TROCAS" is a set of observations collected over a specific datetime interval. In mbdata_df
, each TROCAS is a non-overlapping subset of rows. The "parameters" listed below (EXOSonde_parameters
) correspond to a subset of columns.
EXOSonde_parameters = ['Temp °C', 'ODO mg/L', 'pH', 'Turbidity FNU', 'Chlorophyll µg/L']
obs_parameter = pn.widgets.Select(
name='Parameter',
value=EXOSonde_parameters[0],
options=EXOSonde_parameters,
width=150
)
trocas_nbr = pn.widgets.Select(
name='TROCAS Number',
value='5',
options=[tr for tr in mbdata_df.TROCAS_nbr.unique()],
width=100
)
def mbdata_points_tr(ds, obs_param, TROCAS_nbr=5):
selected = ds.select(TROCAS_nbr=TROCAS_nbr)
return selected.to(hv.Points, ['longitude', 'latitude'], [obs_param, 'date_time'], [])
selpoints = mbdata_points.apply(
mbdata_points_tr,
obs_param=obs_parameter.param.value,
TROCAS_nbr=trocas_nbr.param.value
)
hv.Points.hist()
hvplot.hist()
In the first plot with hist1 alone, a change to the TROCAS Number or Parameter does not update the x-axis and y-axis ranges. In the panel with both hist1 and hist2 plots, the hist1 behaves differently: the x axis now updates dynamically, though the y axis range is still fixed. In that panel, the hist2 plot updates the range on both axes, but the data are not actually plotted when a new Parameter is chosen, nor is it plotted when the original Parameter ("Temp oC") is selected again. (The behavior of hist2 is identical when plotted in a panel by itself without hist1).
In all plots, the x-axis label always updates correctly.
To fully update the histogram plots that have problems after selecting a new Parameter, the panel cell must be rerun.
hv.Points.hist
histogram scheme¶hist1 = selpoints.hist(adjoin=False)
pn.Row(
pn.Column(trocas_nbr, obs_parameter),
hist1.opts(width=800, height=200, toolbar='above')
)
hvplot.hist
histogram scheme¶def histogram(ds, obs_param):
return ds.data.hvplot.hist(y=obs_param)
hist2 = selpoints.apply(histogram, obs_param=obs_parameter.param.value)
pn.Column(
pn.Row(trocas_nbr, obs_parameter),
hist1.opts(width=800, height=200, toolbar='above'),
hist2.opts(width=800, height=200, toolbar='above')
)
print(selpoints)
:DynamicMap [] :Points [longitude,latitude] (Temp °C,date_time)
print(hist1)
:DynamicMap [] :Histogram [Temp °C] (Temp °C_frequency)
print(hist2)
:DynamicMap [] :Histogram [Temp °C] (Temp °C_count)
holoviews.streams.RangeXY
in cell 8¶from holoviews.streams import RangeXY
hist1 = selpoints.hist(adjoin=False, streams=[RangeXY(transient=True)])
Exception: Nesting a DynamicMap inside a DynamicMap is not supported. Ensure that the DynamicMap callback returns an Element or (Nd)Overlay. If you have applied an operation ensure it is not dynamic by setting dynamic=False.
Row
[0] HoloViews(DynamicMap)
[1] Column
[0] Select(name='TROCAS Number', options=['1', '2', '3', ...], value='5', width=100)
[1] Select(name='Parameter', options=['Temp °C', 'ODO mg/L', ...], value='Temp °C', width=150)
dynamic=False
to the above geopoints.hist()
statement removes the error, but the behavior returns to the same old non-dynamic axes problem.framewise
in cell 8¶Tried adding opts(normalize=dict(framewise=True))
, but an error was produced.
from holoviews.streams import Selection1D
, etc). See also http://earthml.pyviz.org/topics/Carbon_Flux.html