.opts not working when overlaying elements

Hello,

I have a program where i have a scatter plot working on Bokeh Serve,

...
def draw_holoview_xvsy(data):
    return hv.Points([[data[0][i], data[1][i]] for i in range(len(data[0]))])


figure_xvsy_holoview_pipe = Pipe(data=np.array([[-100, 0, 100], [-100, 0, 100]]))
figure_xvsy_holoview_dmap = hv.DynamicMap(draw_holoview_xvsy, streams=[figure_xvsy_holoview_pipe])
figure_xvsy_holoview_dmap = dynspread(datashade(figure_xvsy_holoview_dmap)).opts(width=600, height=600,
                                                                     tools=['xwheel_zoom', 'ywheel_zoom', 'box_zoom', 'pan'],
                                                                     active_tools=['xwheel_zoom', 'pan'],
                                                                     default_tools=['reset', 'save', 'hover'],
                                                                     show_grid=True, title='X vs Y')
figure_xvsy_holoview_hvplot = renderer.get_plot(figure_xvsy_holoview_dmap, curdoc())
figure_xvsy_holoview_hvplot.state.output_backend = "webgl"

... #Changing name and labels programatically
figure_xvsy_holoview_dmap.opts(xlabel=x_label, ylabel=y_label, title=y_label + ' vs ' + x_label)
figure_xvsy_holoview_pipe.send(data=np.array([data2plot.iloc[:, 0], data2plot.iloc[:, 1]]))

This works as expected and correctly as im showing in the following GIF.

But now i want to overlay a curve which represents a linear regression of the scatter plot, im doing it as follows:

...
def draw_holoview_xvsy(data):
    return hv.Points([[data[0][i], data[1][i]] for i in range(len(data[0]))])

def draw_holoview_xvsy_linear(data):
    fit = np.polyfit(data[0][:], data[1][:], 1, full=True)
    minx = np.min(data[0][:])
    maxx = np.max(data[0][:])
    slope = fit[0][0]
    intercept = fit[0][1]
    curvedata = np.array([[minx, maxx], [minx * slope + intercept, maxx * slope + intercept]])

    return hv.Curve(dict(x=curvedata[0], y=curvedata[1]))


figure_xvsy_holoview_pipe = Pipe(data=np.array([[-100, 0, 100], [-100, 0, 100]]))
figure_xvsy_holoview_dmap = hv.DynamicMap(draw_holoview_xvsy, streams=[figure_xvsy_holoview_pipe])
figure_xvsy_holoview_dmap = dynspread(datashade(figure_xvsy_holoview_dmap))

figure_xvsy_linear_holoview_pipe = Pipe(data=np.array([[-100, 0, 100], [-100, 0, 100]]))
figure_xvsy_linear_holoview_dmap = hv.DynamicMap(draw_holoview_xvsy_linear, streams=[figure_xvsy_linear_holoview_pipe])
figure_xvsy_linear_holoview_dmap = dynspread(datashade(figure_xvsy_linear_holoview_dmap, cmap=["red"]))

figure_xvsy_holoview_dmap = (figure_xvsy_holoview_dmap * figure_xvsy_linear_holoview_dmap).opts(width=600, height=600,
                                                                     tools=['xwheel_zoom', 'ywheel_zoom', 'box_zoom', 'pan'],
                                                                     active_tools=['xwheel_zoom', 'pan'],
                                                                     default_tools=['reset', 'save', 'hover'],
                                                                     show_grid=True, title='X vs Y')

figure_xvsy_holoview_hvplot = renderer.get_plot(figure_xvsy_holoview_dmap, curdoc())
figure_xvsy_holoview_hvplot.state.output_backend = "webgl"

... #Changing name and labels programatically
figure_xvsy_holoview_dmap.opts(xlabel=x_label, ylabel=y_label, title=y_label + ' vs ' + x_label)
figure_xvsy_holoview_pipe.send(data=np.array([data2plot.iloc[:, 0], data2plot.iloc[:, 1]]))
figure_xvsy_linear_holoview_pipe.send(data=np.array([data2plot.iloc[:, 0], data2plot.iloc[:, 1]]))

And now the labels dont change and the xwheel, ywheel and hoover tools dont show.

Im wondering why the title, labels and tools are not working properly when overlaying these two plots.

Thank you in advance.

Josu Catalina.

Any idea?

Seem to have missed this issue, sorry about that. So let’s start with some unrelated comments:

figure_xvsy_holoview_hvplot = renderer.get_plot(figure_xvsy_holoview_dmap, curdoc())
figure_xvsy_holoview_hvplot.state.output_backend = "webgl"

This does nothing, you rendering the object, then changing the rendering backend. When it renders it again later it remembers nothing about this option. You can change this option globally with:

hv.renderer('bokeh').webgl = True

Now to your actual issue. I suspect this line isn’t applying properly:

figure_xvsy_holoview_dmap.opts(xlabel=x_label, ylabel=y_label, title=y_label + ' vs ' + x_label)

When applying .opts on a DynamicMap I suspect it ends up making a copy of the object so you may have to be reassign it to the same variable:

figure_xvsy_holoview_dmap = figure_xvsy_holoview_dmap.opts(xlabel=x_label, ylabel=y_label, title=y_label + ' vs ' + x_label)

I can’t quite figure out the issue with the tools yet but maybe just try targeting those options to a specific element:

figure_xvsy_holoview_dmap = (figure_xvsy_holoview_dmap * figure_xvsy_linear_holoview_dmap).opts(
    hv.opts.RGB(width=600, height=600, tools=['xwheel_zoom', 'ywheel_zoom', 'box_zoom', 'pan'],
                active_tools=['xwheel_zoom', 'pan'], default_tools=['reset', 'save', 'hover'],
                show_grid=True, title='X vs Y')
)