Reputation: 1003
I need to setup single bokeh figure with multiple glyphs and just subset of glyphs should be selectable (i.e. action is triggered after mouse click on certain glyph). After many trials and errors I found a way to set nonselection_glyph property of glyph to None (see code below). Is it the most efficient way to set a glyph unselectable (or disable changes after selection)?
from bokeh.plotting import figure, curdoc
from bokeh.layouts import column
from bokeh.models import ColumnDataSource
TOOLS = "tap"
p = figure(title="Some Figure", tools=TOOLS)
patches_source = ColumnDataSource(dict(x=[[1, 3, 2], [3, 4, 6, 6]], y=[[2, 1, 4], [4, 7, 8, 5]], alphas = [0.8, 0.3], colors=["firebrick", "navy"], name=['A', 'B']))
circles_source = ColumnDataSource(dict(x=[5, 7, 6], y=[2, 1, 4], alphas = [1.0, 1.0, 1.0], colors=["firebrick", "navy", "greeb"], name=['A', 'B', 'C']))
cglyph = p.circle(x='x', y='y', source=circles_source, size=25, line_width=2, alpha = 'alphas', color='colors')
pglyph = p.patches(xs='x', ys='y', source=patches_source, line_width=2, alpha = 'alphas', color='colors')
pglyph.nonselection_glyph = None #makes glyph invariant on selection
def callback_fcn(attr, old, new):
if new['1d']['indices']:
print('Newly selected: {}'.format(new['1d']['indices'][-1]))
else:
print('Nothing selected')
print("{} - {} - {}".format(attr, old, new))
cglyph.data_source.on_change('selected',callback_fcn)
curdoc().add_root(column(p))
Upvotes: 5
Views: 752
Reputation: 9630
You can create the TapTool manually and set the renderers attribute, which will be the list of renderers where you want to use the tool:
from bokeh.plotting import figure, curdoc
from bokeh.layouts import column
from bokeh.models import ColumnDataSource
from bokeh.models.tools import TapTool
p = figure(title="Some Figure", tools='')
patches_source = ColumnDataSource(dict(
x=[[1, 3, 2], [3, 4, 6, 6]], y=[[2, 1, 4], [4, 7, 8, 5]],
alphas = [0.8, 0.3], colors=["firebrick", "navy"],
name=['A', 'B']
))
circles_source = ColumnDataSource(dict(
x=[5, 7, 6], y=[2, 1, 4],
alphas=[1.0, 1.0, 1.0], colors=["firebrick", "navy", "greeb"],
name=['A', 'B', 'C']
))
cglyph = p.circle(
x='x', y='y', source=circles_source, size=25,
line_width=2, alpha='alphas', color='colors'
)
pglyph = p.patches(
xs='x', ys='y', source=patches_source,
line_width=2, alpha = 'alphas', color='colors'
)
tap = TapTool(renderers=[cglyph])
tools = (tap)
p.add_tools(*tools)
def callback_fcn(attr, old, new):
print("{} - {} - {}".format(attr, old, new))
cglyph.data_source.selected.on_change('indices',callback_fcn)
curdoc().add_root(column(p))
Note: Alternatively you can ser a list of renderer names
Upvotes: 3