LoginSignup
9
11

More than 5 years have passed since last update.

bekeh+pythonでリアルタイムプロット

Last updated at Posted at 2018-09-03

数値計算をブラウザでリアルタイムプロットしたい

bokehを利用していい感じのリアルタイムプロットが出来るようになったのでメモ
jsを用いてやろうとしていましたが、あまりうまくいかなかったので少し回り道してみました
bokeh_plot.png

コード全文

こちらを実行すれば動きます

myplot.py
# myplot.py
from bokeh.plotting import figure, curdoc
from bokeh.driving import linear
import numpy as np
import random

p = figure(plot_width=400, plot_height=400)
######重要###########
p.x_range.follow="end"
p.x_range.follow_interval = 20
p.x_range.range_padding=0
#####################
r1 = p.line([], [], color="firebrick", line_width=2)
r2 = p.line([], [], color="navy", line_width=2)

ds1 = r1.data_source
ds2 = r2.data_source

@linear()
def update(step):
    ds1.data['x'].append(step)
    ds1.data['y'].append(np.sin(step/10))
    ds2.data['x'].append(step)
    ds2.data['y'].append(np.cos(step/10))
    ds1.trigger('data', ds1.data, ds1.data)
    ds2.trigger('data', ds2.data, ds2.data)

curdoc().add_root(p)

# Add a periodic callback to be run every 500 milliseconds
curdoc().add_periodic_callback(update, 100)

解説

必要なライブラリを用意

from bokeh.plotting import figure, curdoc
from bokeh.driving import linear
import numpy as np
import random

figureを定義(400×400)

p = figure(plot_width=400, plot_height=400)

x軸の設定(重要)

p.x_range.follow="end"
p.x_range.follow_interval = 20
p.x_range.range_padding=0

follow...x軸をある値で追従する。今回はendなので、最大値を追従。
interval...ストリーミング間隔
padding...ストリーミング速度を加える?今回は0なので特に意味なし。

documents
https://bokeh.pydata.org/en/latest/docs/reference/models/ranges.html

データフレームの生成

r1 = p.line([], [], color="firebrick", line_width=2)
r2 = p.line([], [], color="navy", line_width=2)

ds1 = r1.data_source
ds2 = r2.data_source

p.line()...figureの".line(x,y,...)"メソッドを利用することで線を描写(pはfigureのインスタンス)
r1.data_source...生成したデータセットをここにぶち込めばいいみたい

デコレータ

@linear()

@linear...decoratorというらしい。連続データを生成している?以下のドキュメントを参照してください。おそらくですが、bokeh内ですでにlinearという関数が定義されていて、@linearで呼び出して続く関数を修飾しているのだと思われます。

おすすめ:Pythonのデコレータについて(Qiita)
https://qiita.com/mtb_beta/items/d257519b018b8cd0cc2e
デコレータのdocument(Bokeh)
http://bokeh.pydata.org/en/0.11.1/docs/reference/driving.html

データの生成&更新

def update(step):
    ds1.data['x'].append(step)
    ds1.data['y'].append(np.sin(step/10))
    ds2.data['x'].append(step)
    ds2.data['y'].append(np.cos(step/10))
    ds1.trigger('data', ds1.data, ds1.data)
    ds2.trigger('data', ds2.data, ds2.data)

updateという関数を定義します。引数はstepで。triggerはよくわかりません。
trigger("名前", x, y)のような感じ?

ブラウザに反映

curdoc().add_root(p)

# Add a periodic callback to be run every 500 milliseconds
curdoc().add_periodic_callback(update, 100)

現在のPを返す
curdoc().add_root(p)...現在のfigureを表示
curdoc().add_periodic_callback(update, 100)...updateを実行して、100msでコールバック
curdoc()のdocument
https://bokeh.pydata.org/en/latest/docs/reference/io.html

感想

やはりpythonで完結しているものは理解しやすいです。jsの勉強もコツコツ頑張ります。

9
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
11