Python Bokeh JSCallback, линейный график фильтрации на основе Select - PullRequest
0 голосов
/ 20 марта 2020

У меня возникли проблемы с написанием кода в функции JSCallback в Python Bokeh.

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

Например, если у меня есть набор данных для различных серий (A, B, C, D). Я хотел бы сделать так, чтобы выбор «A» в поле выбора показывал только те серии на линейном графике, «B», чтобы показать B et c. Это эквивалентно моей фильтрации набора данных (например, с использованием функции lo c в Pandas) перед построением графика данных. Я старался изо всех сил экстраполировать из документации, но безрезультатно. Вот пример сценария. Я знаю, что «var z == f» неверно, но я не знаю, как отфильтровать данные в коде обратного вызова JS. Заранее спасибо.

import pandas as pd
from bokeh.io import show
from bokeh.layouts import column, widgetbox
from bokeh.models import ColumnDataSource, CustomJS, Select
from bokeh.models.widgets import Dropdown
from bokeh.plotting import figure


df = pd.DataFrame(data = {"A": [1,2,3,4,5],
                          "B": [6,7,8,9,10],
                          "C": [11,12,13,14,15],
                          "D": [16,17,18,19,20],
                          "day":[100,101,102,103,104]})

df = df.melt(id_vars = ["day"], var_name = "var",  value_name = "val")
source = ColumnDataSource(dict (val = df["val"],
                                day = df["day"]))


dropdown = Select(title ="Variable", value = "A", options = ["A","B","C","D"])



p = figure(plot_height = 300, plot_width = 800)                 
p.line("day", "val", source= source)


callback = CustomJS(args = dict(source=  source), code = """

data = source.data;
var f = cb.obj_value
var z = data["variable"]
var z == f

source.change.emit()


""")


dropdown.js_on_change("value", callback)

combined= column(p, widgetbox(dropdown))

show(combined)

1 Ответ

1 голос
/ 20 марта 2020

Если вы хотите что-то преобразовать или отфильтровать, не меняйте источники данных. Для этого в Bokeh есть представления, фильтры и преобразования.

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

import pandas as pd
from bokeh.layouts import column
from bokeh.models import ColumnDataSource, CustomJS, Select
from bokeh.plotting import figure, show

df = pd.DataFrame(data={"A": [1, 2, 3, 4, 5],
                        "B": [6, 7, 8, 9, 10],
                        "C": [11, 12, 13, 14, 15],
                        "D": [16, 17, 18, 19, 20],
                        "day": [100, 101, 102, 103, 104]})

source = ColumnDataSource({c: v.values for c, v in df.items()})

initial_value = "A"
dropdown = Select(title="Variable", value=initial_value, options=["A", "B", "C", "D"])

p = figure(plot_height=300, plot_width=800)
l = p.line("day", initial_value, source=source)

dropdown.js_on_change("value", CustomJS(args=dict(line=l),
                                        code="line.glyph.y = {field: cb_obj.value};"))

show(column(p, dropdown))
...