Dear holoviews forum,
I would like to realize the following use case with bokeh/holoviews:
I want to make a scatter plot of a two-dimensional data set.
The data set is too large to be sensibly visualized with bokeh (say, some 100k to a million points) - on the other hand, the ability to interact with individual points (e.g. via the hover tool) is very valuable.
In order to get the best of both worlds, I would like to show a full view of the plot in the beginning using holoviews.operation.datashader.datashade
, but then add an overlay with the bokeh scatter plot when the user has zoomed in enough to have a manageable number of points in the view.
My question is: How do I achieve this?
What I did so far (just in case this is helpful for the maintainers of the docs):
After looking through the gallery (e.g. Mandelbrot / Nyyaxi hover) and finding what I was looking for, I started reading the holoviews documentation. My first thought was to use the holoviews hooks
but it seems those are executed only once (after the initial plot has been rendered).
I then looked through the bokeh documentation and came across the LODEnd / LODStart events - which would seem to be the events I want to attach a callback to.
However, dabbling around with the holoviews plot objects, I didn’t figure out whether/where those events are exposed in holoviews.
I then discovered that holoviews has a different way of customizing interactivity.
I looked through the available streams, which do provide things like PlotSize
but I didn’t find an equivalent to LODEnd
/ LODStart
.
So, before heading off into a dead end I thought - better ask
I’m new to holoviews but have some python experience. I’m happy to put some work into it and prepare an example for the gallery if desired - I think this use case can be interesting to a wider audience.
Best,
Leopold
P.S. Here is some code in case someone wants to quickly dabble around
import holoviews as hv
from holoviews.operation.datashader import datashade
import numpy as np
hv.notebook_extension('bokeh')
np.random.seed(1)
points = hv.Points(np.random.multivariate_normal((0,0), [[0.1, 0.1], [0.1, 1.0]], (5000,)),label="Points")
dynamic_hover = (datashade(points, width=400, height=400) * points)
dynamic_hover.opts(hv.opts.Points(tools=['hover'], alpha=0.0, hover_alpha=0.2))