Как обновить источник в JavaScript Callback Bokeh в Python?

Я адаптирую этот ответ для моего случая, когда мне нужен интерактивный автономный график, на котором ползунок выбирает, какой столбец данных будет отображаться на гистограмме. (Автономный режим крайне важен, я не могу запустить сервер Bokeh, поэтому требуется обратный вызов JavaScript.)

Данные представляют собой прямоугольник с плавающей точкой со 100 строками в каждом из 38 столбцов, каждый из которых имеет строковые метки, такие как '40' и т. д. (это как панды .read_csv() по умолчанию обрабатывает числа в заголовке.) Вот пример из левого верхнего угла (3x3, плюс метки строк и столбцов):

        # ,        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,

Приведенный ниже код создает график для первого столбца, но не обновляет график при перемещении ползунка.

Подчеркивая это, я подозреваю, что проблема связана с кодом JavaScript, хотя ColumnDataSource остается для меня немного загадочным. (Более простой словарь числовых меток столбцов для списков чисел в столбце не работает как datasource_available, хотя соответствует варианту использования связанного ответа.)

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 ответ

Решение

Вопрос в CustomJS код, как вы подозревали. Есть две вещи, которые необходимо исправить.

  1. Боке устарела get() а также set() методы и заменили их getv() или же setv(), Однако предпочтительным способом доступа к свойствам модели или их изменения является использование обычных атрибутов JavaScript, например: source_visible.data,

  2. Боке устарела trigger('change') и заменил его change.emit(),

Фиксированный CustomJS код:

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 и предупреждения отображаются в консоли браузера. Вот инструкции по открытию консоли в разных браузерах.

Другие вопросы по тегам