When a hvplot.scatter is colored by a non-numeric column, the streams.Selection1D() doesnt fire when points are tapped.
holoviews.version = 1.19.1
Here is a MRE:
import panel as pn
import hvplot.pandas
import holoviews as hv
from holoviews import streams
import param
pn.extension()
# Minimal dataset
df = pd.DataFrame({
'Amount': [100000, 200000, 150000, 300000],
'Year': [2018, 2019, 2020, 2021],
'km': [10000, 25000, 50000, 75000],
'Range': [400, 450, 500, 550],
'Cat': ['a', 'b', 'b', 'c']
})
class MREApp(param.Parameterized):
x_axis = param.Selector(objects=['Amount', 'Year'], default='Amount')
y_axis = param.Selector(objects=['Year', 'Range'], default='Year')
color_by = param.Selector(objects=['Amount', 'Year', 'km', 'Range', 'Cat'], default='Year')
tap_stream = streams.Selection1D()
@param.depends('x_axis', 'y_axis', 'color_by')
def cross_plot(self):
if pd.api.types.is_numeric_dtype(df[self.color_by]):
# This changes the tap_stream.index when a point is clicked:
color_args = {'c': self.color_by, 'cmap': 'Viridis', 'colorbar': True}
else:
# This DOES NOT change the tap_stream.index when a point is clicked:
color_args = {'by': self.color_by, 'cmap': 'Category20'}
plot = df.hvplot.scatter(x=self.x_axis, y=self.y_axis, **color_args).opts(
tools=['tap'], width=600, height=400
)
self.tap_stream.source = plot
return plot
@param.depends('tap_stream.index')
def show_selection(self):
if self.tap_stream.index:
idx = self.tap_stream.index[0]
selected = df.iloc[idx]
return pn.pane.Str(f"Selected Point: {selected.to_dict()}")
else:
return pn.pane.Str("No selection")
def panel(self):
return pn.Column(
pn.Param(self.param, widgets={'x_axis': pn.widgets.Select, 'y_axis': pn.widgets.Select, 'color_by': pn.widgets.Select}),
self.cross_plot,
self.show_selection
)
app = MREApp()
pn.serve(app.panel())