Show / Hide Labels Layout based on zoom level

Hi,
I have a quad graph with label layout ontop of the quad, which I would like to hide/show based on the zoom level of the plot (if the quads gets too small, the labels will just be rendered ontop of each other).
Here is an example of the graph (taken from the Bokeh site):

import numpy as np
N = 9
x = np.linspace(-2, 2, N)
y = x**2

source = ColumnDataSource(dict(
        left=x,
        top=y,
        right=x-x**3/10 + 0.3,
        bottom=y-x**2/10 + 0.5,
        names=['a','b','c','a','b','c','a','b','c']
    )
)

plot = figure(plot_width=400, plot_height=400,
             sizing_mode="fixed",
             tools=['xpan', 'xwheel_zoom'],
             active_scroll='xwheel_zoom')

glyph = Quad(left="left", right="right", top="top", bottom="bottom", fill_color="#b3de69")
plot.add_glyph(source, glyph)

labels = LabelSet(x='left', y='top', text='names',
              x_offset=0, y_offset=0, source=source, render_mode='canvas')
plot.add_layout(labels)

show(plot)

I thought that a custom JS would be the solution. I would appreciate help on how to write it:
plot.x_range.js_on_change('end', CustomJS(?))

Any other solution would be great as well.

Thanks,
Shay

Something along the lines of this:

zoom_cb = CustomJS(args=dict(labels=labels,plot=plot)
                   ,code='''
                   //what is the current range of the plot?
                   var xr = [plot.x_range.start,plot.x_range.end]
                   var yr = [plot.y_range.start,plot.y_range.end]
                   //how did I know that's how to get at these range properties?
                   //console.log(plot) // then looking at the plot object in the JS console,
                   //drill down to find the properties you're after
                   //alternatively, most of the time you can drill down into the python object equivalent as well                   
                   //next, need some sort of conditional to determine IF the labels should be shown
                   //just basic JS if statement syntax
                   //making up a condition here just to illustrate
                   //if the xrange is less than three, turn off the labels' visibility
                   if (xr[1]-xr[0] < 3){
                           labels.visible = false
                           }
                   else {labels.visible = true}
                   '''
                   )

If you want to get into managing the visibility of individual labels (the above only toggles the visibility of all labels at once), you’d likely want to add a “label_alpha” field in your source, point the LabelSet’s alpha property to follow that field, and then manipulate the values in that field in the callback.

2 Likes

This is great - it works! thank you.