Bokeh: Обновите график рассеяния из группы флажков, используя Custom JS для фильтрации источника - PullRequest
0 голосов
/ 28 марта 2020

Я не очень знаком с Java Script и нуждаюсь в помощи этого замечательного сообщества!.

Я пытаюсь создать диаграмму рассеяния с прикрепленной группой флажков, чтобы выбрать различные группы для построения. Фиктивные данные следующие:

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)

source = ColumnDataSource(data)

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

Я хотел бы добавить группу флажков с буквой в качестве возможных вариантов выбора и отобразить значения только выбранных букв. Было бы здорово, если бы это можно было сделать с помощью Java Script для встраивания в документ HTML.

Заранее спасибо.

1 Ответ

0 голосов
/ 28 марта 2020
import pandas as pd
from bokeh.layouts import row
from bokeh.models import ColumnDataSource, CDSView, CheckboxGroup, CustomJS, BooleanFilter
from bokeh.plotting import figure, show

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)

source = ColumnDataSource(data)

plot = figure()
active_letter = 'A'
f = BooleanFilter(booleans=[l == active_letter for l in data['letter']])
uniq_letters = sorted(set(data['letter']))
cg = CheckboxGroup(labels=uniq_letters, active=[uniq_letters.index(active_letter)])
cg.js_on_change('active',
                CustomJS(args=dict(source=source, f=f),
                         code="""\
                             const letters = cb_obj.active.map(idx => cb_obj.labels[idx]);
                             f.booleans = source.data.letter.map(l => letters.includes(l));
                             source.change.emit();
                         """))

plot.circle('x', 'y', line_width=2, source=source,
            view=CDSView(source=source, filters=[f]))

show(row(cg, plot))
...