Skip to content
Bryan Van de Ven edited this page Mar 21, 2014 · 9 revisions

A common need with a hierarchal object graphs such as those generated by Bokeh plots is to be able to quickly locate objects of interest (which may correspond directly to visible elements in the scene) and examine or update their attributes. Consider the following notional diagram of a Bokeh plot:

Here you can see that the plot has many elements:

  • renderers (blue)
  • data sources (purple)
  • guides (orange)
  • annotations (green)
  • tools (red)
  • overlays (yellow)

Many of these objects are not directly contained by the plot directly, but are contained by other objects that are contained by the plot. Moreover, these objects may have different attributes from each other:

Name ID Type Category
plot 11 Plot plot title="plot"
left_axis 22 LinearAxis axis dim=0 tick_color="blue
pan_tool 33 PanTool tool dims=["h"]
datasource1 44 ColumnDataSource source foo=[...] bar=[...]
taxes 55 Line glyph color="red" dash="2 2"
income 66 Line glyph color="blue" alpha=0.5

Here, all the objects share a common set of attributes: Name, ID, Type, and Category but also have many more attributes specific to their type. This is similar to a "NoSQL" database. We would like a simple means to define selectors for querying this object structure, to get ahold of the objects we are interested in.

Syntax Examples

Let's say we would like to get ahold of a line renderer we have named "taxes". Here is how me might do that:

Bokeh.select({type: "Line", name: "taxes"})

Alternatively, a syntax like this could be supported as well:

Bokeh.select().type("Line").name("taxes")

Another example, let's find the legend label for the taxes renderer (that happens to have the label value "taxes"):

Bokeh.select().type("Label").value("taxes")

Get all the axes of a plot:

Bokeh.select({"category": "axis"})

Or get only the vertical ones:

Bokeh.select({"category": "axis"}).dimension(1)

A very useful selector might look for all the subplots on a grid plot in a certain column:

Bokeh.select().children(my_grid_plot).column(-1)

Disjunction

All the examples above are implicitly "AND" clauses: i.e, "find the object with this category, AND this dimension". We'd like to be able to handle "OR" clauses as well. Propose:

Bokeh.select().category("axis").or().category("grid")

Alternative proposal:

(Bokeh.select().category("axis")).or(Bokeh.select().category("grid"))

Naming

Propose to add a name field to all objects. This can be specified by the user:

line(x, y, name="my data")

Otherwise a name is generated based off the type:

line(x, y) # name -> "line_2", e.g.

Updating

To update all the objects found by a selector, propose:

Bokeh.update( <some selector>, {"foo": 10, "bar": 20} )