How can I call a JavaScript function from Python using Bokeh?

旧城冷巷雨未停 提交于 2019-12-13 02:53:05

问题


I have this scenario:

  1. I have some data (in a pandas dataframe) that I use to draw my plots
  2. When I press a button (built by a bokeh widget) I can call my callback method and I do my computation in python.
  3. But now I want to send the computed data back to the user in order to show a question in a wizard. So I need to run some JavaScript function.

I was thinking of creating a dummy button and run the click method of this button from python. But I think this is not possible.

So, how can I run a JavaScript function directly from python?


回答1:


As of Bokeh 0.12.6, being able to make these kinds of "Remote Procedure Calls" is still an open feature request.

In the mean time, your best bet is to add a CustomJS callback to some property of some model. The CustomJS can execute whatever JS code you want (including calling other JS functions) and will trigger any the property is updated.

Here's an example that shows calling CustomJS whenever a slider is changed. For your use case you might add an invisible circle glyph, and attach a CustomJS to the glyph's size attribute. Changing glyph.size is how you can "call" the function.

from bokeh.layouts import column
from bokeh.models import CustomJS, ColumnDataSource, Slider
from bokeh.plotting import Figure, output_file, show

output_file("js_on_change.html")

x = [x*0.005 for x in range(0, 200)]
y = x

source = ColumnDataSource(data=dict(x=x, y=y))

plot = Figure(plot_width=400, plot_height=400)
plot.line('x', 'y', source=source, line_width=3, line_alpha=0.6)

callback = CustomJS(args=dict(source=source), code="""
    var data = source.data;
    var f = cb_obj.value
    x = data['x']
    y = data['y']
    for (i = 0; i < x.length; i++) {
        y[i] = Math.pow(x[i], f)
    }
    source.change.emit();
""")

slider = Slider(start=0.1, end=4, value=1, step=.1, title="power")
slider.js_on_change('value', callback)

layout = column(slider, plot)

show(layout)



回答2:


Minimal example showing what Bryan answered me

from bokeh.plotting import figure
from bokeh.models.sources import ColumnDataSource
from bokeh.models.callbacks import CustomJS
from bokeh.io import curdoc
from bokeh.layouts import column
from bokeh.models.widgets import Button

plot = figure(
    width=600,
    height=600,
)

source = ColumnDataSource({
    'x': [1, 2, 3],
    'y': [4, 5, 6],
})
cr = plot.circle(
    x='x', y='y',
    source=source, size=10, color="navy", alpha=0.5
)

callback = CustomJS(args=dict(source=source), code="""
    console.log('This code will be overwritten')
""")
cr.glyph.js_on_change('size', callback)

def cb():
    js_code = """
        alert('Hello!');
    """
    callback.code = js_code  # update js code
    cr.glyph.size += 1       # trigger the javascript code

bt = Button(
    label="Start Bokeh",
    button_type="success"
)
bt.on_click(cb)

curdoc().add_root(column([bt, plot]))


来源:https://stackoverflow.com/questions/45288570/how-can-i-call-a-javascript-function-from-python-using-bokeh

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!