2016-01-15 2 views
0

Я хотел бы использовать Bokeh для построения фрагмента объекта серии панд на фигуре со статическим диапазоном. Я хотел бы управлять положением среза внутри объекта серии с помощью ползунка. Ширина среза будет статичной.Ползунок Bokeh для управления срезом данных, представленным на осях со статическим диапазоном?

В качестве примера, если бы мне был представлен 2-секундный срез временного ряда скорости, слайдер контролировал бы значение «timeStart», указывающее начало окна. Значения x представленных временных рядов будут варьироваться от timeStart до timeStart + 2.

Это является частью более крупной проблемы, и поэтому у меня есть 2 дополнительные ограничения:

  • Оси варьируются значения на рисунке являются статическими.

  • Данные должны быть предварительно рассчитаны (то есть данные не генерируются параметрическим уравнением, которое может использоваться в функции обратного вызова).

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

import bokeh.plotting as bkP 
import bokeh.models as bkM 
from bokeh.io import vform 
import numpy as np 
bkP.output_notebook() 

from bokeh.io import vform 

x = np.linspace(0, 10, 500) 
y = np.sin(x) 

source = bkP.ColumnDataSource(data=dict(x=x,y=y))#,fr=np.zeros(len(x)))) 

plot = bkP.figure(x_range=(0,100),y_range=(-1,1), plot_width=400, plot_height=400) 

plot.line('x', 'y', source=source, line_width=3, line_alpha=0.6) 

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

    var data = source.get('data'); 
    var start = frame.get('value') 

    oldX = data['x'] 
    oldY = data['y'] 

    for (i = -10; i < 10; i++) { 
     x[i] = fr+i 
     y[i] = y[fr+i] 
    } 

    source.trigger('change'); 

""") 

fr_slider = bkM.Slider(start=0, end=len(x), value=0, step=1, # 
        title="frame", callback=callback) 

callback.args["frame"] = fr_slider 

layout = bkP.hplot(
    plot, 
    vform(fr_slider), 
) 

bkP.show(layout) 

ответ

2

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

from bokeh.io import output_notebook, show, vform 
from bokeh.plotting import figure, Figure 
from bokeh.models import ColumnDataSource, Slider, CustomJS 
import numpy as np 

output_notebook() 

x = np.sort(np.random.uniform(0, 100, 2000)) 
y = np.sin(x*10) + np.random.normal(scale=0.1, size=2000) 
fig = Figure(plot_height=400) 

mask = (x > 0) & (x < 2) 

source1 = ColumnDataSource(data={"x":x[mask], "y":y[mask]}, id="source1") 
source2 = ColumnDataSource(data={"x":x, "y":y}, id="source2") 
line = fig.line(x="x", y="y", source=source1) 

callback = CustomJS(args=dict(s1=source1, s2=source2), code=""" 
var d1 = s1.get("data"); 
var d2 = s2.get("data"); 
var start = cb_obj.get("value"); 
var s = Bokeh._.findIndex(d2["x"], function(v){return v > start;}); 
var e = Bokeh._.findIndex(d2["x"], function(v){return v > start + 2;}); 
d1["x"] = []; 
d1["y"] = []; 
for(i=s;i<=e;i++){ 
    d1["x"].push(d2["x"][i]); 
    d1["y"].push(d2["y"][i]); 
} 
s1.trigger("change"); 
""") 
slider = Slider(start=0, end=100, step=2, callback=callback) 
show(vform(slider, fig)) 

или вы можете показать все данные и изменить диапазон х в функции обратного вызова:

from bokeh.io import output_notebook, show, vform 
from bokeh.plotting import figure, Figure 
from bokeh.models import ColumnDataSource, Slider, CustomJS 
import numpy as np 

output_notebook() 

x = np.sort(np.random.uniform(0, 100, 2000)) 
y = np.sin(x*10) + np.random.normal(scale=0.1, size=2000) 
fig = Figure(plot_height=400, x_range=(0, 2)) 

source = ColumnDataSource(data={"x":x, "y":y}) 
line = fig.line(x="x", y="y", source=source) 

callback = CustomJS(args=dict(x_range=fig.x_range), code=""" 
var start = cb_obj.get("value"); 
x_range.set("start", start); 
x_range.set("end", start+2); 
""") 
slider = Slider(start=0, end=100, step=2, callback=callback) 
show(vform(slider, fig)) 
+0

где я могу найти Bokeh ._. findIndex? Моя программа отлично работает, если я просто устанавливаю e равным start и s равно 0, но когда я пытаюсь использовать эту функцию findIndex, она ломается (мой сюжет не обновляется) – user3273208