I'm trying to combine Holoviews' Pointdraw functionality with its Sample functionality (I couldn't find a specific page, but it is shown in action here http://holoviews.org/gallery/demos/bokeh/mandelbrot_section.html)
Specifically, I want to have two subplots with interactivity. The one on the left shows a colormap, and the one on the right shows a sample (a linecut) of the colormap. This is achieved with .sample
. Inside this right plot I'd like to have points that can be drawn, moved, and removed, typically done with pointdraw
. I'd then also like to access their coordinates once I am done moving, which is possible when following the example from the documentation.
Now, I've got the two working independently, following the examples above. But when combined in the way that I have, this results in a plot that looks like this:
It has the elements I am looking for, except the points cannot be interacted with. This is somehow related to Holoviews' streams, but I am not sure how to solve it. Would anyone be able to help out?
The code that generates the above:
%%opts Points (color='color' size=10) [tools=['hover'] width=400 height=400]
%%opts Layout [shared_datasource=True] Table (editable=True)
import param
import numpy as np
import holoviews as hv
hv.extension('bokeh', 'matplotlib')
from holoviews import streams
def lorentzian(x, x0, gamma):
return 1/np.pi*1/2*gamma/((x-x0)**2+(1/2*gamma)**2)
xs = np.arange(0,4*np.pi,0.05)
ys = np.arange(0,4*np.pi,0.05)
data = hv.OrderedDict({'x': [2., 2., 2.], 'y': [0.5, 0.4, 0.2], 'color': ['red', 'green', 'blue']})
z = lorentzian(xs.reshape(len(xs),1),2*np.sin(ys.reshape(1,len(ys)))+5,1) + lorentzian(xs.reshape(len(xs),1),-2*np.sin(ys.reshape(1,len(ys)))+5,1)
def dispersions(f0):
points = hv.Points(data, vdims=['color']).redim.range(x=(xs[0], xs[-1]), y=(np.min(z), np.max(z)))
point_stream = streams.PointDraw(data=points.columns(), source=points, empty_value='black')
image = hv.Image(z, bounds=(xs[0], ys[0], xs[-1], ys[-1]))
return image* hv.VLine(x=f0) + image.sample(x=f0)*points
dmap = hv.DynamicMap(dispersions, kdims=['f0'])
dmap.redim.range(f0=(0,10)).redim.step(f0=(0.1))
I apologize for the weird function that we are plotting, I couldn't immediately come up with a simple one.