简体   繁体   中英

Show text annotations on selection in Bokeh

I have a little Bokeh plot with data points and associated text labels. What I want is for the text labels to only appear when the user selects points with the box select tool. This gets me close:

from bokeh.plotting import ColumnDataSource,figure,show

source = ColumnDataSource(
    data=dict(
        x=test[:,0],
        y=test[:,1],
        label=[unquote_plus(vocab_idx[i]) for i in range(len(test))]))

TOOLS="box_zoom,pan,reset,box_select"
p = figure(plot_width=400, plot_height=400,tools=TOOLS)
p.circle(x='x',y='y', size=10, color="red", alpha=0.25,source=source)

renderer = p.text(x='x',y='y',text='label',source=source)

renderer.nonselection_glyph.text_alpha=0.

show(p)

This is close, in that if I draw a box around some points, those text labels are shown and the rest are hidden, but the problem is that it renders all the text labels to start (which is not what I want). The initial plot should have all labels hidden, and they should only appear upon a box_select.

I thought I could start by rendering everything with alpha=0.0, and then setting a selection_glyph parameter, like this:

...
renderer = p.text(x='x',y='y',text='label',source=source,alpha=0.)
renderer.nonselection_glyph.text_alpha=0.
renderer.selection_glyph.text_alpha=1.
...

But this throws an error:

AttributeError: 'NoneType' object has no attribute 'text_alpha'

When trying to access the text_alpha attribute of selection_glyph .

I know I could use a hover effect here or similar, but need the labels to default to not being visible. An alternative, but not ideal, solution would be to have a toggle button that switches the labels on and off, but I'm not sure how to do that either.

What am I doing wrong here?

As of version 0.11.1 , the value of selection_glyph is None by default. This is interpreted by BokehJS as "don't do anything different, just draw the glyph as normal". So you need to actually create a selection_glyph . There are two ways to do this, both demonstrated here:

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

Basically, they are

by hand

Create an actual Circle Bokeh model, something like:

selected_circle = Circle(fill_alpha=1, fill_color="firebrick", line_color=None)
renderer.selection_glyph = selected_circle

OR

using glyph method parameters

Alternatively, as a convenience Figure.circle accepts paramters like selection_fill_alpha or selection_color (basically any line or fill or text property, prefixed with selection_ ) :

p.circle(..., selection_color="firebrick")

Then a Circle will be created automatically and used for renderer.selection_glyph


I hope this is useful information. If so, it highlights that there are two possible ways that the project could be improved:

  • updating the docs to be explicit and highlight that renderer.selection_glyph is None by default

  • changing code so that renderer.selection_glyph is just a copy of renderer.glyph by default (then your original code would work)

Either would be small in scope and ideal for a new contributor. If you would be interested in working up a Pull Request to do either of these tasks, we (and other users) would certainly be grateful for the contribution. In which case, please just make an issue first at

https://github.com/bokeh/bokeh/issues

that references this discussion, and we can provide more details or answer any questions.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM