Search code examples
pythonbokeh

Updating the location of a horizontal line based on a slider value in Bokeh


I want to draw a plot that has both curves based on (x, y) data and horizontal lines. I want to update the curves and lines based on the state of a slider. How can I do this?

I know how to update the curve based on the slider state, by using ColumnDataSource. I also know how to draw a horizontal line, by using Span. But I don't know how to combine these two.

For now, I am doing a hack by representing the horizontal line by an array of identical y-values, which I am storing in the ColumnDataSource, and by using line() instead of Span. I'm just wondering if this is the intended way to solve this problem.

I found this same question asked by user Thornhale in a 2017 comment to this answer. But the comment was not answered.


Solution

  • Bokeh offers you the opportunity to link sources and widgets using js_link or js_on_change. In your case the js_link option is very handy.

    from bokeh.layouts import column
    from bokeh.models import Span, Slider
    from bokeh.plotting import figure, show, output_notebook
    output_notebook()
    
    p = figure(width=300, height=300)
    p.line(x=[0,1,2], y=[0,1,2])
    
    vline = Span(location=0, dimension='height', line_color='red', line_width=3)
    hline = Span(location=0, dimension='width', line_color='green', line_width=3)
    p.renderers.extend([vline, hline])
    
    sv = Slider(start=0, end=2, value=0, step=1, margin=10)
    sv.js_link('value', vline, 'location')
    
    sh = Slider(start=0, end=2, value=0, step=1, margin=10)
    sh.js_link('value', hline, 'location')
    
    layout = column(sv, sh, p)
    show(layout)
    

    linked spans