2017-12-01 8 views
1

bokeh 앱에서 source.stream을 사용할 때 타임 스탬프를 어떻게 사용해야합니까? 여기 보케 (Bokeh) 서버를 사용하여 범위에서 시간 걸기를 사용하는 방법

은 내가 bokeh serve test.py를 사용하여 서버를 시작하면

# test.py 
from bokeh.io import curdoc, output_notebook, show 
from bokeh.models import Line, Plot, ColumnDataSource, Range1d 
from bokeh.layouts import column 
import numpy as np 

delta_time = np.timedelta64(1,'s') 
start_time = np.datetime64('2017-01-01T00:00:00') 

tail_length = 30 

timerange = Range1d(start_time - tail_length * delta_time, start_time) 
source = ColumnDataSource(dict(time=[start_time], y=[0.5])) 
plot = Plot(width=200, height=100, x_range=timerange, y_range=Range1d(0,1)) 
plot.add_glyph(source, Line(x='time',y='y')) 

def callback(): 
    # update axis 
    layout.children[0].x_range.start += delta_time 
    layout.children[0].x_range.end += delta_time 

    # update data 
    source.stream(dict(time=[source.data['time'][-1] + delta_time], 
         y=[np.random.rand()]), tail_length) 

layout = column(plot) 

curdoc().add_root(layout) 

# move 10 datapoints into the sliding window before the server starts 
for _ in range(10): 
    callback() 

# then add a new datapoint each second 
curdoc().add_periodic_callback(callback, 1000) 

을 달성하기 위해 노력하고있어 최소한의 예입니다, 출력이 보여 callback()을 나타냅니다

enter image description here

기능은 inteded로 작동합니다. 그러나 두 번째 후 callbackcurdoc().add_periodic_callback에서 호출 될 때, 그것은

enter image description here

콜백 동안 x_range 변경, 내가 callback() 정의 내부 인쇄 문 print(layout.children[0].x_range.end, type(layout.children[0].x_range.end))을 추가하는 방법을 조사하기 위해, 아무 것도 표시되지 않습니다. x_range 좌표 유형이 동일하게 유지되는 것처럼 보이지만 다소 이상한 이유로 콜백을 curdoc().add_periodic_callback이라고 할 때 다른 문자열 표현을 사용합니다.

2017-12-01 21:54:45,520 Starting Bokeh server version 0.12.11 (running on Tornado 4.5.2) 
2017-12-01 21:54:45,522 Bokeh app running at: http://localhost:5006/test 
2017-12-01 21:54:45,522 Starting Bokeh server with process id: 22665 
# printing the 10 initial callback calls here 
2017-01-01T00:00:01 <class 'numpy.datetime64'> 
2017-01-01T00:00:02 <class 'numpy.datetime64'> 
2017-01-01T00:00:03 <class 'numpy.datetime64'> 
2017-01-01T00:00:04 <class 'numpy.datetime64'> 
2017-01-01T00:00:05 <class 'numpy.datetime64'> 
2017-01-01T00:00:06 <class 'numpy.datetime64'> 
2017-01-01T00:00:07 <class 'numpy.datetime64'> 
2017-01-01T00:00:08 <class 'numpy.datetime64'> 
2017-01-01T00:00:09 <class 'numpy.datetime64'> 
2017-01-01T00:00:10 <class 'numpy.datetime64'> 
2017-12-01 21:54:47,961 200 GET /test (::1) 31.59ms 
2017-12-01 21:54:48,381 101 GET /test/ws?bokeh-protocol-version=1.0&bokeh-session-id=jekHIMP5Eo5kjzDDgdMgqba2bNxjbQEpDcBmgET6aHfL (::1) 0.68ms 
2017-12-01 21:54:48,381 WebSocket connection opened 
2017-12-01 21:54:48,381 ServerConnection created 
# printing callback from curdoc().add_periodic_callback here 
1483228810001 seconds <class 'numpy.timedelta64'> 
1483228810002 seconds <class 'numpy.timedelta64'> 
1483228810003 seconds <class 'numpy.timedelta64'> 

실제로 무엇이 일어나고 있습니까?

답변

1

매우 흥미로운 동작! 당신은 나뭇잎 서버에 URL을 쳤을 때를 통해, 그 루프를 실행하고 계산하려면

for _ in range(10): 
    callback() 

루프에서 10 개 콜백을 볼 수 있듯이 다음 결과가 반환되고, 웹 소켓은 후 등

연결되어 그 ColumnDataSource는 갑자기 datetime의 float 표현으로 나타납니다!

다음 코드는 float을 datetime으로 다시 변환하면 그래프가 다시 "작동"하게됩니다.

루프를 주석 처리 했으므로 첫 번째 값만 변환하면됩니다.

from bokeh.io import curdoc, output_notebook, show 
from bokeh.models import Line, Plot, ColumnDataSource, Range1d 
from bokeh.layouts import column 
import numpy as np 


delta_time = np.timedelta64(1,'s') 
start_time = np.datetime64('2017-01-01T00:00:00') 

tail_length = 30 

timerange = Range1d(start_time - tail_length * delta_time, start_time) 

source = ColumnDataSource(dict(time=[start_time], y=[0.5])) 
plot = Plot(width=500, height=500, x_range=timerange, y_range=Range1d(0,1)) 
plot.add_glyph(source, Line(x='time',y='y')) 


def callback(): 
    # update axis 
    # convert long to datetime 
    layout.children[0].x_range.start = np.datetime64(layout.children[0].x_range.start, 'ms') + delta_time 
    layout.children[0].x_range.end = np.datetime64(layout.children[0].x_range.end, 'ms') + delta_time 

    # update data 
    source.stream(dict(time=[np.datetime64(source.data['time'][-1],'ms') + delta_time], 
         y=[np.random.rand()]), tail_length) 

layout = column(plot) 
doc = curdoc() 
doc.add_root(layout) 

#move 10 datapoints into the sliding window before the server starts 
# for _ in range(10): 
#  callback() 

# then add a new datapoint each second 
doc.add_periodic_callback(callback, 1000)