I’m trying to generate a histogram plot that responds dynamically to two Select 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, but I can’t get this to work without issues. Either the axis ranges don’t update, or they do but the plot is not actually generated, or an extraneous extra plots needs to be present. I’ve tried these two schemes:
In a 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 and the data are plotted, 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.
So, the only time I’m successful, with hist1 only, is when I add an extra, unnecessary histogram plot in the same pane. Even then, the y-axis range doesn’t update dynamically.
I’ve created a notebook that demonstrates the problem. It uses panel version 0.8.0, holoviews 1.12.7 and hvplot 0.5.2; I also tested it with panel 0.7.0 and 0.6.2, holoviews 1.12.5, and hvplot 0.4.0. I’m pasted below the code from the notebook. This functionality is part of a larger panel dashboard I’m developing, that you can check out for context on Heroku at https://trocasdata-1.herokuapp.com; click on the Data Browser tab.
I’m still fairly new with the holoviz ecosystem, so I don’t know where the problem is exactly, including whether it has anything to do with panel per se. Any help would be really appreciated!
import pandas as pd import holoviews as hv import hvplot.pandas import panel as pn hv.extension('bokeh', logo=False) pn.extension(logo=False) # Load parquet data and create holoviews Points from dataframe mbdata_df = pd.read_parquet('./data/merged_1minbinned_df.parq', engine='fastparquet') mbdata_points = hv.Points(mbdata_df, kdims=['longitude', 'latitude']) # panel widgets for selecting a "TROCAS" and a parameter EXOSonde_parameters = ['Temp °C', 'ODO mg/L', 'pH', 'Turbidity FNU', 'Chlorophyll µg/L'] obs_parameter = pn.widgets.Select( name='Parameter', value=EXOSonde_parameters, 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 ) # Data filtering based on widget selections 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 ) # hist1: 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') ) # hist2: 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) # Plot the two histogram schemes in a Column panel driven by a common control widget pn.Column( pn.Row(trocas_nbr, obs_parameter), hist1.opts(width=800, height=200, toolbar='above'), hist2.opts(width=800, height=200, toolbar='above') )