2017-02-22 37 views
0

Я пытаюсь построить интерактивный график в Боке. До сих пор, допустим, у меня есть тепловая карта, как показано ниже. На простом английском языке:Как выбрать точки данных, основанные на RangeSlider в Bokeh?

  • Я использую прямоугольник для рисования прямоугольников, создающих тепловую карту.
  • Я добавляю RangeSlider.
  • Я прикрепляю js_callback к изменениям диапазона.
  • В пользовательском обратном вызове я могу получить начальный и конечный диапазон ползунка диапазона.

То, что я не уверен в том, как затем выбрать что-либо с ним. This link (cb_obj.selected ['1d']. Индексы) показывает, что извлекаются все выбранные точки данных. Но как делать наоборот?

Другими словами:

Как выбрать все прямоугольники, которые находятся между значениями а и Ь?

Ниже приведен код с вещами, которые я уже понял.

from math import pi 
from bokeh.io import show 
from bokeh.models import ColumnDataSource, HoverTool, 
LinearColorMapper, CategoricalColorMapper, ColorBar, LogColorMapper, 
LogTicker 
from bokeh.plotting import figure 
from bokeh.models.callbacks import CustomJS 

col = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] 
row = ['A', 'B', 'C' , 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 
'N', 'O', 'P'] 

mapper = LogColorMapper(palette="Viridis256", low=min_value, 
high=max_value) 
source = ColumnDataSource(data = dict (
     row = test['plate_row'], 
    col = test['plate_col'], 
    values = test['Melt Temp'])) 

TOOLS = "reset, tap,box_select, hover,save,pan,box_zoom,wheel_zoom" 

p = figure(title="Plate Heatmap", x_range = (0.0,25.0), y_range = 
list(reversed(row)), 
     x_axis_location="above", plot_width=650, plot_height=400, 
     tools=TOOLS) 

r1 = p.rect(x="col", y="row", width=1, height=1, 
     source=source, 
     fill_color={'field': 'values', 'transform': mapper}, 
     line_color=None) 

callback = CustomJS(args=dict(source=source), code=""" 
    var data = source.data; 
    var inds = cb_obj.selected['1d'].indices; 
    var lower_bound = cb_obj.start; 
    var upper_boudn = cb_obj.end; 
    // WHAT DO I DO NEXT? 
    source.trigger('change'); 
""") 

range_slider = widgetbox(RangeSlider(start=min_value, end=max_value, 
range= (min_value, max_value), step=0.1, title="Hit Threshold")) 
range_slider.js_on_change('range', callback) 

color_bar = ColorBar(color_mapper=mapper, ticker=LogTicker(), 
       label_standoff=12, border_line_color=None, location= 
(0,0)) 
p.add_layout(color_bar, 'left') 
layout = column(range_slider, p) 
show(layout)  # show the plot 

ответ

0

Хотя я не смог найти способ установить то, что выбрано или нет, я нашел способ добиться такого же результата. Это, пожалуй, лучший пример того, как можно использовать сервер Bokeh. Для достижения этого же эффекта, нужно сделать следующее:

  1. Заменить функцию обратного вызова JSCustom с обновлением функции Python. Функция udpate содержит код для обновления ColumnDataSource.
  2. Замените событие js_on_change просто событием on_change , прикрепленным к слайдеру.
  3. Разместите вышеуказанный код вместе с функцией обновления в пределах «main.py» в папке, названной в честь приложения.
  4. Запустите сервер bokeh с помощью «bokeh serve --show INSERTAPP_NAME».

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