What's the command to “reset” a bokeh plot?

前端 未结 3 438
生来不讨喜
生来不讨喜 2021-01-04 07:46

I have a bokeh figure that has a reset button in the toolbar. Basically, I want to \"reset\" the figure when I update the data that I\'m plotting in the figure. How can I do

相关标签:
3条回答
  • 2021-01-04 08:24

    Example with a radiogroup callback, that's the best way I found to reset while changing plots, just get the range of the data and set it to the range:

    from bokeh.plotting import Figure
    from bokeh.models import ColumnDataSource, CustomJS, RadioGroup
    from bokeh.layouts import gridplot
    from bokeh.resources import CDN
    from bokeh.embed import file_html
    
    x0 = range(10)
    x1 = range(100)
    y0 = [i for i in x0]
    y1 = [i*2 for i in x1][::-1]
    
    
    fig=Figure()
    
    source1=ColumnDataSource(data={"x":[],"y":[]})
    source2=ColumnDataSource(data={"x0":x0,"x1":x1,"y0":y0,"y1":y1})
    
    p = fig.line(x='x',y='y',source=source1)
    
    callback=CustomJS(args=dict(s1=source1,s2=source2,px=fig.x_range,py=fig.y_range),  code="""
        var d1 = s1.get("data");
        var d2 = s2.get("data");
        var val = cb_obj.active;
    
        d1["y"] = [];
        var y = d2["y"+val];
        var x = d2["x"+val];
    
        var min = Math.min( ...y );
        var max = Math.max( ...y );
    
        py.set("start",min);
        py.set("end",max);
    
        var min = Math.min( ...x );
        var max = Math.max( ...x );
    
        px.set("start",min);
        px.set("end",max);
    
        for(i=0;i<=y.length;i++){
            d1["y"].push(d2["y"+val][i]);
            d1["x"].push(d2["x"+val][i]);
        }
    
        s1.trigger("change");
        """)
    
    radiogroup=RadioGroup(labels=['First plot','Second plot'],active=0,callback=callback)
    
    grid = gridplot([[fig,radiogroup]])
    
    outfile=open('TEST.html','w')
    outfile.write(file_html(grid,CDN,'Reset'))
    outfile.close()
    

    The Bokeh website is seriously lacking in examples for different ways to set callbacks for the different widgets.

    0 讨论(0)
  • 2021-01-04 08:41

    UPDATE: A PR has been submitted for this feature. After Bokeh 0.12.16 is released, the following will work:

    from bokeh.io import show
    from bokeh.layouts import column
    from bokeh.models import Button, CustomJS
    from bokeh.plotting import figure
    
    p = figure(tools="reset,pan,wheel_zoom,lasso_select")
    p.circle(list(range(10)), list(range(10)))
    
    b = Button()
    b.js_on_click(CustomJS(args=dict(p=p), code="""
        p.reset.emit()
    """))
    
    show(column(p, b))
    

    As of Bokeh 0.12.1 there is no built in function to do this. It would possible to make a custom extension that does this. However, that would take a little work and experimentation and dialogue. If you'd like to pursue that option, I'd encourage you to come to the public mailing list which is better suited to iterative collaboration and discussion than SO. Alternatively, please feel free to open a feature request on the project issue tracker

    0 讨论(0)
  • 2021-01-04 08:48

    I was struggling to make it work with Bokeh 2.2.1, but this JS p.reset.emit() does not seem to work.

    What worked for me was to manually set the Figure renderers attribute to an empty list inside a callback function, called via on_click(). This only works with a Bokeh server running, though:

    $ bokeh serve --show example.py
    

    example.py:

    from bokeh.layouts import column
    from bokeh.models import Button
    from bokeh.plotting import curdoc, figure
    
    p = figure(tools="reset,pan,wheel_zoom,lasso_select")
    p.circle(list(range(10)), list(range(10)))
    
    def clear_plot(attr):
        p.renderers = []
    
    b = Button(label="Clear plot")
    b.on_click(clear_plot)
    
    curdoc().add_root(column(p, b))
    
    0 讨论(0)
提交回复
热议问题