How to update a source in a JavaScript Callback of Bokeh in Python?

我与影子孤独终老i 提交于 2019-12-11 16:13:11

问题


I am adapting this answer for my case, where I want an interactive, standalone graph where the slider selects which column of the data to plot in a bar chart. (Standalone is crucial, I cannot run a Bokeh server, thus the need for JavaScript callbacks.)

The data is a rectangle of floats with 100 rows in each of the 38 columns, which all have string labels like '40' etc. (This is how pandas .read_csv() handles numerics in the header by default.) Here is a sample from the top left corner (3x3, plus the row and column labels):

        # ,        40,        41,        42,
   1.00000,   1.00000,   0.99287,   0.98489,
   2.00000,   1.00000,   0.99348,   0.98626,
   3.00000,   1.00000,   0.99433,   0.98922,

The code below produces the graph for the first column but does not update the graph upon moving the slider.

By poking at it, I suspect the issue is with the JavaScript code, though ColumnDataSource remains a bit mysterious to me. (A more straightforward dictionary of numeric column labels to lists of the numbers in the column does not work as datasource_available, though corresponds to the linked answer's use case.)

datadf = pd.read_csv('male_survival_by_pctile.csv')
datadf.set_index('# ',inplace=True)
years = range(40,77)
data = {}
data_available = {}

for year in years:
    data[year] = {'top':datadf[str(year)],'x':range(1,101)}
data_available = ColumnDataSource.from_df(datadf)

from bokeh.core.properties import field
from bokeh.io import curdoc, output_notebook, show
from bokeh.layouts import layout, column
from bokeh.models import (ColumnDataSource, HoverTool, SingleIntervalTicker,
                          Slider, Button, Label, CustomJS)
from bokeh.plotting import figure

output_notebook()

source_visible = ColumnDataSource(data=dict(x=range(1,101),top=data_available[str(years[0])]))
source_available = ColumnDataSource(data=data_available)

plot = figure(output_backend="webgl")
plot.xaxis.ticker = SingleIntervalTicker(interval=.01)
plot.xaxis.axis_label = "Income percentile"
plot.yaxis.ticker = SingleIntervalTicker(interval=.05)
plot.yaxis.axis_label = "Survival rate"

label = Label(x=1.1, y=18, text=str(years[0]), text_font_size='70pt', text_color='#eeeeee')
plot.add_layout(label)

plot.vbar(top='top',x='x',width=1,source=source_visible)

slider = Slider(start=years[0], end=years[-1], value=years[0], step=1, title="Age")

slider.callback = CustomJS(
    args=dict(source_visible=source_visible,
              source_available=source_available), code="""
        var selected_function = cb_obj.get('value').toString();
        // Get the data from the data sources
        var data_visible = source_visible.get('data');
        var data_available = source_available.get('data');
        // Change bar height to the selected value
        data_visible.top = data_available[selected_function];
        // Update the plot
        source_visible.trigger('change');
    """)

layout = column(slider, plot)

show(layout)

回答1:


The issue is in the CustomJS code as you suspected. There are two things that need to be fixed.

  1. Bokeh has deprecated get() and set() methods and replaced them by getv() or setv(). However, the preferred way of accessing or modifying model properties is through usual JavaScript attributes, e.g., source_visible.data.

  2. Bokeh has deprecated trigger('change') and replaced it by change.emit().

The fixed CustomJS code:

slider.callback = CustomJS(
    args=dict(source_visible=source_visible,
              source_available=source_available), code="""
        var selected_function = cb_obj.value.toString();
        // Get the data from the data sources
        var data_visible = source_visible.data;
        var data_available = source_available.data;
        // Change bar height to the selected value
        data_visible.top = data_available[selected_function];
        // Update the plot
        source_visible.change.emit();
    """)

JavaScript errors and warnings are seen in the browser's console. Here are instructions for opening the console in different browsers.



来源:https://stackoverflow.com/questions/51234876/how-to-update-a-source-in-a-javascript-callback-of-bokeh-in-python

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