PointDrawTool for multiple figures

I have multiple figures with a merged toolbar. I would like to use the PointDrawTool in a way such that it does only adds or edits a point on the figure the mouse is currently on and not on both figures. Here is a example with a couple figures.

import numpy as np
from bokeh.io import curdoc
from bokeh.layouts import gridplot
from bokeh.models import ColumnDataSource
from bokeh.plotting import figure

N = 200
x = np.linspace(0, 4*np.pi, N)
y = np.sin(x)
z = np.cos(x)
source = ColumnDataSource(data=dict(x=x, y=y, z=z))

plot1 = figure(plot_height=400, plot_width=400, title="my sine wave",
               tools="crosshair,pan,reset,save,wheel_zoom",
               x_range=[0, 4*np.pi], y_range=[-2.5, 2.5])
circle1 = plot1.circle('x', 'y', source=source)

plot2 = figure(plot_height=400, plot_width=400, title="my cosine wave",
               tools="crosshair,pan,reset,save,wheel_zoom",
               x_range=[0, 4*np.pi], y_range=[-2.5, 2.5])
circle2 = plot2.circle('x', 'z', source=source)

pdt = PointDrawTool(renderers=[circle1, circle2])
plot1.add_tools(pdt)

grid = gridplot([[plot1], [plot2]], toolbar_location='above')

grid.children[1].sizing_mode = 'fixed'
grid.children[1].height = 1000
grid.children[1].width = 500

curdoc().add_root(grid)
curdoc().title = "Point Draw Test"

I have tried various combinations of adding the PointDrawTool to just one or both figures or adding unique PointDrawTools or changing which renderers I add to each tool. Each method seems to work about the same way although sometimes there will be duplicate tools added to the toolbar.

I would prefer to just add one tool to the toolbar and have the PointDrawTool only affect point on the applicable figure but I would also accept if there is a way to have a merged toolbar above the figures with separate individual toolbars on the left of each figure for housing the PointDrawTool. Not sure if this last one is possible. Thoughts? Thank you!

I would like to use the PointDrawTool in a way such that it does only adds or edits a point on the figure the mouse is currently on and not on both figures.

@jbeck The edit tools all operate by updating a data source. If you don’t want multiple glyphs to respond t an edit tool, then the only solution is to not share the data source between the glyphs.

I separated my data into multiple column data sources to handle this. It now performs as I would like except that when I add the PointDrawTool to each figure I have several PointDrawTools show up on the toolbar even though it is a merged toolbar. I have done this with customized HoverTools and Crosshairs but they successfully merged into just one tool. Is this a bug?

Merged toolbars don’t merge the tools themselves. They only merge the buttons on the toolbar and make the merged buttons activate/de-activate multiple underlying tools at a time. Edit tools are more complicated multi-gesture tools that hovers and crosshairs, offhand I am not sure I would expect them to be combined under a single button.

cc @Philipp_Rudiger do you have any thoughts about this?

Yeah, I was thinking they would merge the buttons just like the other tools. I also just discovered the empty value property which is very helpful when would with multiple figures that share a column data source as well.

Any idea if there is a way to modify the behavior of the delete function for this tool? I have data like y1=f(x) and y2=g(x). I could separate into separate column data sources but I think that would be unnecessary overhead, but I also don’t want to delete a corresponding y2 point when I delete a y1 point. I was thinking if I could just set the value of y1 to ‘nan’ or something instead of removing it so that I don’t lose the entire row of data.

They only merge the buttons on the toolbar and make the merged buttons activate/de-activate multiple underlying tools at a time.

I thought I found a sort of workaround for this issue. This methods merges the PointDrawTool for each figure under one button. It works for both moving and deleting points, but it will only place new points on figure1. It also seems to be very slow, especially when deleting points. I cannot share all of it but it goes something like what is below.

pdt = PointDrawTool(renderers=[glyph1, glyph2, glyph3])
plot = GridPlot([[figure1], [figure2], [figure3]], toolbar_location='above')
plot.children[0].toolbar.tools.append(pdt)
figure1.add_tools(pdt)
figure2.add_tools(pdt)
figure3.add_tools(pdt)