Реализация JavaScript обратного вызова для флажков в боке? - PullRequest
0 голосов
/ 10 июня 2019

Короткая версия: флажки bokeh с обратными вызовами JS для построения подмножеств кадра данных?

Более длинная версия: Ответ здесь даетхорошее объяснение множественного выбора, но я хочу сделать то же самое для флажков.Все мои данные находятся в одном фрейме данных pandas, и я использую флажки, чтобы выбрать биты этого фрейма данных для построения.Я считаю, что с флажками это как-то связано с cb_obj.active, но я очень не уверен, как заставить это работать.В частности, мой график включает цветные прямоугольники и текст, вся информация о котором: позиция, текст, цвет, взята из моего кадра данных.И я не знаю, сколько графиков должно быть сделано в обратном вызове, а сколько снаружи.

Насколько я могу судить, обратный вызов вызывает функцию для выполнения фактического построения.

Я знаю, что должен привести минимальный пример, но я не могу думать, как упростить мой коддостаточно ... так что все, что я действительно хочу на данный момент, это пример использования флажков с обратным вызовом JavaScript для построения подмножества фрейма данных.Кто-то, должно быть, сделал это, но я еще не нашел пример!Спасибо.

Ответы [ 2 ]

0 голосов
/ 11 июня 2019

Вот адаптированная версия моего ответа для MultiSelect, на которую вы ссылались:

from bokeh.models import CustomJS, ColumnDataSource, CheckboxGroup, Column

from bokeh.plotting import figure, show
import pandas as pd

data = dict(letter = ['A','A','B','C','B','B','A','C','C','B'], 
x = [1, 2, 1, 2, 3, 2, 2, 3, 2, 3], 
y = ['10','20','10','30','10','40','10','30','10','40'])
data = pd.DataFrame(data)

data_source = ColumnDataSource(data)
source = ColumnDataSource(dict(x = [], y = []))

plot = figure()
plot.circle('x', 'y', line_width = 2, source = source)

callback = CustomJS(args = {'source': source, 'data_source': data_source},
code = """
var data = data_source.data;
var s_data = source.data;
var letter = data['letter'];
var select_vals = cb_obj.active.map(x => cb_obj.labels[x]);
console.log(select_vals);
var x_data = data['x'];
var y_data = data['y'];
var x = s_data['x'];
x.length = 0;
var y = s_data['y'];
y.length = 0;
for (var i = 0; i < x_data.length; i++) {
    if (select_vals.indexOf(letter[i]) >= 0) {
        x.push(x_data[i]);
        y.push(y_data[i]);
        }
}
source.change.emit();
console.log("callback completed");
""")

chkbxgrp = CheckboxGroup(labels = ['A', 'B', 'C'], active=[])
chkbxgrp.js_on_change('active', callback)
layout = Column(chkbxgrp, plot)
show(layout)

Примечания:

  • Обратный вызов не будет работать в Internet Explorer, поскольку он использует функции стрелок, которые IE не поддерживает. Если это проблема, вам нужно сделать отображение, используя что-то кроме функций стрелок
  • как прокомментировал пользователь bigreddot в ответе, который вы указали, это также можно сделать с помощью CDSView с использованием пользовательского фильтра, поскольку GroupFilter не поддерживает несколько значений
0 голосов
/ 11 июня 2019

Вот пример:

from bokeh.plotting import figure, show, output_notebook
from bokeh.models import Slider, CheckboxGroup, CustomJS, ColumnDataSource, CDSView
from bokeh.models.filters import CustomJSFilter
from bokeh.layouts import row
from bokeh.transform import factor_cmap
from bokeh.palettes import Category10_10
output_notebook()

Вы можете использовать CustomJSFilter для расчета индекса отображаемых строк:

from bokeh.sampledata import iris
source = ColumnDataSource(data=iris.flowers)
species = iris.flowers.species.unique().tolist()
checkboxes = CheckboxGroup(labels=species, active=list(range(len(species))))
fig = figure()
filter =  CustomJSFilter(code="""
let selected = checkboxes.active.map(i=>checkboxes.labels[i]);
let indices = [];
let column = source.data.species;
for(let i=0; i<column.length; i++){
    if(selected.includes(column[i])){
        indices.push(i);
    }
}
return indices;
""", args=dict(checkboxes=checkboxes, source=source))

checkboxes.js_on_change("active", CustomJS(code="source.change.emit();", args=dict(source=source)))

fig.scatter("sepal_length", "sepal_width", 
            color=factor_cmap("species", Category10_10, species),
            source=source, view=CDSView(source=source, filters=[filter]))
show(row(checkboxes, fig))

enter image description here

...