概要
普段はArduinoやM5stackなどのマイコンやガジェットをいじってるのですが、何台もセンサーをつないでデータが集まったのはいいものの、それをインタラクティブに可視化する手段があまりない。何かいいのはないか?ということでBokehを見つけて勉強を始めました。
ところが日本語の参考になる記事は多くなく公式ドキュメントやGallery-Bokeh 2.0.0 Documentation、Qiita記事を参考にしましたがなかなか苦労したのでこの記事を見て役に立てれば幸いです。
完成したグラフ
読み込んだcsvをDataframeにし、X-AxisとY-Axisにcsv内のcolumnをSelectを使って選択しグラフ化しています。下グラフの選択範囲をRangetoolで選択し拡大画像が上に描画されるようにしています。
なお今回csvはcsvからbokehグラフ出力の記事のcsvをそのままお借りしています。本来はcolumnが2種類以上あるcsvであればどんなデータでも問題ありません。
結構手こずったけどRangetool×Select完成!#bokeh pic.twitter.com/7m9Fy2683a
— サクヤtypeR 化学工学×AIoT (@typeR_Anonymous) March 22, 2020
実行環境
Windows10
Anaconda
Python3.7
pandas1.0.1
Bokeh 1.4
ソースコード
import pandas as pd
from bokeh.io import curdoc
from bokeh.layouts import column, layout, row
from bokeh.models import RangeTool, Select
from bokeh.plotting import figure
df = pd.read_csv('bachelors.csv')
columns = sorted(df.columns)
#create figure function
def create_figure():
xs = df[x.value].values
ys = df[y.value].values
x_title = x.value.title()
y_title = y.value.title()
kw = dict()
kw['title'] = "%s vs %s" % (x_title, y_title)
p = figure(plot_height=250, plot_width=600, tools="pan,box_zoom,reset,save",
**kw,x_range=(xs[10], xs[15]))
p.xaxis.axis_label = x_title
p.yaxis.axis_label = y_title
p.line(x=xs, y=ys)
range_select = figure(title="選択ボックスの中央と端をドラッグして、上の範囲を変更します。",
plot_height=250, plot_width=600, y_range=p.y_range,
tools="", toolbar_location=None )
range_tool = RangeTool(x_range=p.x_range)
range_tool.overlay.fill_color = "navy"
range_tool.overlay.fill_alpha = 0.2
range_select.line(x=xs, y=ys)
range_select.ygrid.grid_line_color = None
range_select.add_tools(range_tool)
range_select.toolbar.active_multi = range_tool
range_select.xaxis.axis_label = x_title
range_select.yaxis.axis_label = y_title
controls = column(x, y, width=200)
graph = column(p, range_select)
return controls, graph
#update function
def update(attr, old, new):
layout.children[:] = create_figure()[:]
#create select widget
x = Select(title='X-Axis', value='Year', options=columns)
x.on_change('value', update)
y = Select(title='Y-Axis', value='Agriculture', options=columns)
y.on_change('value', update)
controls = column(x, y, width=200)
graph = create_figure()[1]
layout = row(controls, graph)
curdoc().add_root(layout)
実行方法
以下をターミナルで打ち込み実行すると、Bokeh serverが立ち上がりローカルホストからctrl+クリックでブラウザにグラフを表示させることができます。
bokeh serve range_select.py
おわりに
インタラクティブなグラフが手軽にできると見てるだけで結構楽しいです。60行程度のコードでできるのも驚きです。
Dataframeでグラフ化できると機械学習モデルの結果を同時に表示させたりsqlから多種のデータを読みこんで描画させたり、など応用が広がってよさそうです。
参考
Gallery-Bokeh 2.0.0 Documentation
@kimisyoさんのBokeh記事@Qiita
csvからbokehグラフ出力