#python #bokeh
#python #bokeh
Вопрос:
Прошу прощения, но я не могу создать какой-либо воспроизводимый код для этого вопроса, поскольку он довольно противоречив.
Итак, у меня есть таблица данных bokeh, и я выполняю с ней некоторую фильтрацию, используя 4 выпадающих списка. Таблица данных обновляется на основе значения выпадающего списка, и обновления были написаны на JS. Фильтрация работает, как ожидалось, но, как ни странно, для некоторых очень специфических комбинаций выпадающих значений она ничего не отображает в таблице данных. Мне было интересно, была ли это проблема с моими данными, но я принудительно преобразовал все в строки, и это все равно вызвало у меня ту же проблему.
Обновления написаны здесь:
combined_callback_code = """
var data = source.data;
var original_data = original_source.data;
var origin = origin_select_obj.value;
var classification = classification_select_obj.value;
var currency = currency_select_obj.value;
var grade = grade_select_obj.value;
for (var key in original_data) {
data[key] = [];
for (var i = 0; i < original_data['Origin'].length; i) {
if ((origin === "ALL" || original_data['Origin'][i] === origin) amp;amp;
(classification === "ALL" || original_data['Classification'][i] === classification) amp;amp;
(currency === "ALL" || original_data['Currency'][i] === currency) amp;amp;
(grade === "ALL" || original_data['BrokenPct'][i] === grade)){
data[key].push(original_data[key][i]);
}
}
}
target_obj.change.emit();
source.change.emit();
"""
# define the filter widgets, without callbacks for now
origin_list = ['ALL'] df['Origin'].unique().tolist()
origin_select = Select(title="Origin:", value=origin_list[0], options=origin_list)
classification_list = ['ALL'] df['Classification'].unique().tolist()
classification_select = Select(title="Classification:", value=classification_list[0], options=classification_list)
currency_list = ['ALL'] df['Currency'].unique().tolist()
currency_select = Select(title = "Currency:", value=currency_list[0], options = currency_list)
grade_list = ["ALL"] df['BrokenPct'].unique().tolist()
grade_select = Select(title = "Grade:", value = grade_list[0], options = grade_list)
# now define the callback objects now that the filter widgets exist
generic_callback = CustomJS(
args=dict(source=source,
original_source=original_source,
origin_select_obj=origin_select,
classification_select_obj=classification_select,
currency_select_obj = currency_select,
grade_select_obj = grade_select,
target_obj=data_table),
code=combined_callback_code
)
# finally, connect the callbacks to the filter widgets
origin_select.js_on_change('value', generic_callback)
classification_select.js_on_change('value', generic_callback)
currency_select.js_on_change('value', generic_callback)
grade_select.js_on_change('value', generic_callback)
Ответ №1:
Правильный способ обновления табличных данных в вашем обратном вызове JS заключается в следующем:
var data = {};
//build your data here
source.data = data;
Где source
— источник данных столбца Bokeh для вашей таблицы данных.
Вам не нужно использовать:
source.change.emit();
Вы делаете это только тогда, когда заменяете только часть своих данных, например, один столбец таблицы.
И если data_table
это ваш объект Bokeh DataTable, то также пропустите выполнение:
target_obj.change.emit();
Дата таблицы обновляется автоматически при обновлении ее ColumnDataSource.
Посмотрите на этот простой пример:
from bokeh.io import show
from bokeh.layouts import widgetbox
from bokeh.models import ColumnDataSource, Slider, DataTable, TableColumn, CustomJS
source = ColumnDataSource(dict(x = list(range(6)), y = [x ** 2 for x in range(6)]))
columns = [TableColumn(field = "x", title = "x"), TableColumn(field = "y", title = "x**2")]
table = DataTable(source = source, columns = columns, width = 320)
slider = Slider(start = 1, end = 20, value = 6, step = 1, title = "i", width = 300)
callback_code = """ i = slider.value;
new_data = {"x": [1, 2, 3, 4, 5], "y": [1, 4, 9, 16, 25]}
table.source.data = new_data
table.width = 320 i * 25; """
callback = CustomJS(args = dict(slider = slider, table = table), code = callback_code)
slider.js_on_change('value', callback)
show(widgetbox(slider, table))
Комментарии:
1. Замечательно. Большое спасибо.