Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does this Bokeh Column Data Source Work?

Tags:

python

bokeh

I am trying to get a better understanding about the column data source in Bokeh (for Python). I found this code, but I can't seem to find the documentation that explains some things I am looking for, For instance:

  1. Where is the callback from the lasso_select tool? I want to see where the expected functionality is described.
  2. How is the functionality of the lasso_select described in code? (What if I want to change it?)
  3. What is happening to the column data source so that the circles outside the lasso-select region change appearance? (I want to know how I can use the column data source for more complex visualization than is shown by this demo. So I'd like to know what dictionary field is being manipulated, and how is it being manipulated. For example, is there a hidden "color" field or something like that, which isn't explicit in this code?)
  4. What code causes the figure to be redrawn when a lasso_select action is made?

I have many more questions related to this and the CDSView, but I'll stop here for now.

from bokeh.io import output_file, show
from bokeh.layouts import gridplot
from bokeh.models import ColumnDataSource
from bokeh.plotting import figure

output_file("brushing.html")

x = list(range(-20, 21))
y0 = [abs(xx) for xx in x]
y1 = [xx**2 for xx in x]

# create a column data source for the plots to share
source = ColumnDataSource(data=dict(x=x, y0=y0, y1=y1))

TOOLS = "box_select,lasso_select,help"

# create a new plot and add a renderer
left = figure(tools=TOOLS, plot_width=300, plot_height=300, title=None)
left.circle('x', 'y0', source=source)

# create another new plot and add a renderer
right = figure(tools=TOOLS, plot_width=300, plot_height=300, title=None)
right.circle('x', 'y1', source=source)

p = gridplot([[left, right]])

show(p)

This is related to my previous question, where the only answer was very narrow in explaining for that specific question. However, I am really interested in what's going on under the hood to give the results that are seen. It would help my understanding a lot more if I could know some of those details.

like image 581
Jim Avatar asked Sep 19 '26 03:09

Jim


1 Answers

1) There is no callback. The tool is responsible for defining a selection geometry, and and then hit-testing baed on that geometry. The hit test results are store in a selection property of the data source. Glyph renderers draw glyphs based on the selection property of their data source. If two glyph renderers (even on different plots) share the same data source, they will both draw the same set of selected/nonselected as a result.

2) If you mean the appearance of the normal vs selected vs non-selected objects, how to configure that is described in the docs here:

https://docs.bokeh.org/en/latest/docs/user_guide/styling.html#selected-and-unselected-glyphs

There are also a few properties on the LassoTool object itself, that control, e.g. whether a selection should be made on every mousemove, or only on mouseup, and what the selection overlay looks like. All of these are recorded in the ReferenceGuide. If you are asking how to change the implementation, as with msot everything in Bokeh, the real work is not done in Python, it is done in the JavaScript library BokehJS. The implementation of the LassoTool is here:

https://github.com/bokeh/bokeh/blob/master/bokehjs/src/lib/models/tools/gestures/lasso_select_tool.ts

If you want something fundamentally different you would need to implement your own custom model, including its JavaScript component. There is an entire User's Guide section about building custom extensions:

https://docs.bokeh.org/en/latest/docs/user_guide/extensions.html

3) The Plot is configured with various Renderers, one of which can be a GlyphRenderer. The GlyphRenderer itself does not draw anything, but it configures various sub-glyphs that are used to draw in specific situations:

  • glyph draws "normal" versions of glyphs (i.e. when there is no selection on the data source)
  • selected_glyph draws "selected" versions of glyphs (i.e. the ones inside a lasso or box tool when a selection is active)
  • nonselected_glyph draws the "non-selected" versions of glyphs (i.e. the ones outside a lasso or box tool when a selection is active) By default the non selection glyph is just a copy of the "normal" glyph with the alpha value set very low.
  • hover_glyph draws the "hovered" versions of glyphs (i.e. when a hover tool has inspected them)

You configure the appearance in the different situation by configuring properties on the glyphs that are used in each situation. There are sensible defaults for them, but they can be updated as described in the first link of 2)

4) BokehJS has an internal signal/slots event system that is used (among other things) to request canvas redraws whenever various properties change.

like image 181
bigreddot Avatar answered Sep 20 '26 16:09

bigreddot