5

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))
2
  • It works for me too. Did you find out anything else about settings glyphs to "not selectable"? Are you still using this code? Commented May 21, 2019 at 12:15
  • @LeeviL check my answer, you may still find useful Commented Sep 1, 2019 at 11:34

1 Answer 1

3

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

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.