Как связать входы / элементы управления Bokeh для фильтрации данных? Не могу понять, как заставить входной фильтр отфильтровывать значения, показанные в визуальном - PullRequest
0 голосов
/ 11 января 2020

Я сделал визуализацию Bokeh с Python и пытаюсь понять, как заставить элементы управления / входы изменять данные.

В галерее Bokeh есть пример, который делает то, что я после более продвинутого способа и также имеют код , и мне кажется, что мне не хватает только control.on_change('value', lambda attr, old, new: update()), но я не могу понять, что представляют собой функции update () и select делать.

Вот очень упрощенная версия, где я застрял. Я хочу отфильтровать записи со значением «Полеты», меньшим, чем то, что выбрано на слайдере.

from bokeh.plotting import figure, output_file, ColumnDataSource, show
from bokeh.models import Slider
from bokeh.layouts import column, layout

data = dict(
Flights =        [97, 34, 23, 6, 26, 97, 21, 92, 73, 10, 92, 14, 77, 4, 25, 48, 26, 39, 93],
Not_Cancelled =  [87, 63, 56, 38, 57, 63, 73, 56, 30, 23, 66, 47, 76, 15, 80, 78, 69, 87, 28],
OnTime_Arrivals= [21, 65, 86, 39, 32, 62, 46, 51, 17, 79, 64, 43, 54, 50, 47, 63, 54, 84, 79])
source = ColumnDataSource(data = data)
output_file('index.html')
p = figure()
p.circle('OnTime_Arrivals', 'Not_Cancelled', source = source, size = 20)

MinFlights = Slider(start=0, value = 50, end=100, step=1)
controls = [MinFlights]

inputs = column(*controls, width = 200)
l = layout([[inputs,p]])
show(l)

Я также запутался, почему в какой-то документации указывается Javascript для обратных вызовов, когда я понял предпосылка Боке, чтобы управлять всем Javascript для вас. В идеале я хотел бы сохранить все это в Python.

Извините за такой тупой вопрос. Последние два часа я схожу с ума, удивляясь, почему я не могу заставить такую ​​простую вещь работать, и я собираюсь собирать здесь бананы. Буду искренне признателен за любую помощь.

1 Ответ

0 голосов
/ 11 января 2020

Меня также смущает, почему в какой-то документации указывается, что для обратных вызовов требуется Javascript, когда я понял, что Bokeh управляет всеми Javascript для вас. В идеале я хотел бы сохранить все в Python.

JavaScript не требуется для обратных вызовов, JavaScript - это возможно для обратных вызовов. Реальные Python обратные вызовы всегда возможны, но для их использования необходимо запустить приложение сервера Bokeh . Некоторые варианты использования могут быть лучше и проще с несколькими строчками JavaScript, и некоторые пользователи предпочли бы эту опцию. Боке предоставляет обе возможности.

Ваш вариант использования может быть выполнен в любом случае. Вот полный пример, использующий обратные вызовы JS:

from bokeh.plotting import figure, show
from bokeh.models import Slider, CustomJSFilter, CDSView, ColumnDataSource, CustomJS
from bokeh.layouts import column, layout

data = dict(Flights=[97, 34, 23, 6, 26, 97, 21, 92, 73, 10, 92, 14, 77, 4, 25, 48, 26, 39, 93],
            Not_Cancelled=[87, 63, 56, 38, 57, 63, 73, 56, 30, 23, 66, 47, 76, 15, 80, 78, 69, 87, 28],
            OnTime_Arrivals=[21, 65, 86, 39, 32, 62, 46, 51, 17, 79, 64, 43, 54, 50, 47, 63, 54, 84, 79])
source = ColumnDataSource(data=data)

MinFlights = Slider(start=0, value=50, end=100, step=1)

# this filter selects rows of data source that satisfy the constraint
custom_filter = CustomJSFilter(args=dict(slider=MinFlights), code="""
    const indices = []
    for (var i = 0; i < source.get_length(); i++) {
        if (source.data['Flights'][i] > slider.value) {
            indices.push(true)
        } else {
            indices.push(false)
        }
    }
    return indices
""")
view = CDSView(source=source, filters=[custom_filter])

# force a re-render when the slider changes
MinFlights.js_on_change('value', CustomJS(args=dict(source=source), code="""
   source.change.emit()
"""))

p = figure()
p.circle('OnTime_Arrivals', 'Not_Cancelled', source=source, view=view, size=20)

inputs = column(MinFlights, width=200)
show(layout([[inputs,p]]))

enter image description here

...