皆さん、こんにちは!
今回からPythonのデータ可視化ライブラリである「Bokehを学ぶシリーズ」を行っていきます。
このシリーズで参考にする資料は、Bokeh公式ドキュメントです。
英語版しかありませんので、私の勉強がてら、公式ドキュメントのFirst Stepを更に詳しく解説するようなイメージで進めていきます。


この記事では、第1回目ということで、Bokehとは何なのか触れつつ、公式ドキュメントのFirst Stepの1つ「Creating a simple lin chart plot」を解説していきます。
Contents
Bokehとは?
Bokehは、ブラウザ向けにデータ可視化を行うためのライブラリです。
インタラクティブ(ユーザーが軸の最大最小を変えたり、グラフを拡大したり…)な可視化が可能のため、単純なデータ表示から、ストリーミングデータを使ったダッシュボードのようなものを作成することも可能です。

一般的にブラウザに描画するためには、HTMLやCSS、動きをつけようと思うと、JavaScriptの知識が必要となりますが、Bokehのコードを実行すると、内部でHTMLやJavaScriptを自動で記述し、描画してくれます。
(正しくはTypeScriptのようですが、私にはよくわかりません…)

ともかくとして、こういった便利なライブラリのおかげで、Pythonの知識しかない、私でも簡単にセンスのあるデータ可視化が行えるというわけです。
matplotlibとの違い
Matplotlibとの最も大きな違いは、結果の出力方法でしょう。
データの渡し方や、コードの書き方は非常に似通っていますが、中身は全く異なります。
Matplotlibの出力は画像です。
グラフを書いた後は、pngやjpegなどが通常です。
以下は左側が、Matplotlib、右側はBokehで記述したグラフとなります。
あとは細かいレイアウトが効きにくかったり、Python使い始めの人には十分ですが、最終的に報告書に載せたり、他人に見せるものとしては、少し不向きです。
私の場合、MatplotlibとSeaborn(ハイエンドな描画ライブラリ)を組み合わせて使っています。
一方、Bokehの出力はHTMLです。
そこから画像保存などは出来ますが、1つ目のアウトプットとしては、HTMLとJavaScriptを組み合わせたHTMLファイルで出力されます。

Bokehグラフの使い方
Bokehグラフがインタラクティブな要素だと言いましたが、具体的にどの程度インタラクティブなのか説明していきます。
グラフの左端に小さく表示されている、何やら操作できそうなアイコン…
これらがBokehグラフを作成すると必ず表示される要素です。
どんなグラフを作成しても最低限サポートされている動作と考えて問題ありません。
より作りこめば、スライドバーやチェックボックスなども付け加えられますが、Bokehの基本からは少し外れてしまうので割愛します。
この辺りは実際にグラフを描画してみて、操作してもらった方が早いです。
Bokehグラフで最低限サポートされている動作は以下の7つ(実質5つ)です。
- Bokeh公式ドキュメントへのリンク
- 左クリック+マウス移動でグラフ内の要素を移動
- 矩形で囲った部分を拡大表示(ボックスズーム)
- マウス中ボタン回転で拡大・縮小
- グラフを画像保存
- グラフのリフレッシュ(初期化)
- グラフの使い方ヘルプ

Bokehのインストール
Bokehを初めて使う場合、Pyplからインストールする必要があります。
皆さんおなじみ、pipを使ってインストールしてください。
pip install bokeh
Bokehで折れ線グラフを表示してみる
それではBokehを使ってきましょう。
Bokehをインポートします。
output_notebook()を使うことで、現在使っているバージョンを表示することが出来ます。
2.4.3は5月上旬にリリースされており、現在も積極的な開発が行われているライブラリで、今後の発展も大いに期待できるでしょう。
# Bokehライブラリをインポート
from bokeh.plotting import figure, output_notebook, show
# バージョンを表示する
output_notebook()

次はBokehで簡単な折れ線グラフを書いていきます。
BokehではX軸、Y軸のデータをあらかじめ用意しておく必要があるので、それぞれリストを作成しておきます。
グラフはFigureインスタンス(プロットする箱みたいなもの)を立ち上げておいて、その中にグラフの種類を決めたデータを挿入するイメージです。
最後は、Figureインスタンスをshow()すれば描画完了です。
※p.line()は「p」というFigureインスタンスに折れ線グラフを挿入するイメージ
# 前行でインポートしている場合は不要
# from bokeh.plotting import figure, show
# サンプルデータを作成
# x,yをそれぞれリスト形式
x = [1, 2, 3, 4, 5]
y = [6, 7, 2, 4, 5]
# 新しいプロットの作成
# タイトル、軸ラベルを決定し、figureインスタンスを立ち上げる
p = figure(title="Simple line example", x_axis_label='x', y_axis_label='y')
# 折れ線グラフを軸名とともに作成する
# 折れ線の太さも設定する
p.line(x, y, legend_label="Temp.", line_width=2)
# 結果を描画する
show(p)

Bokehで折れ線グラフを複数表示してみる
次はグラフを複数書いていきます。
複数書く場合も、XとYのデータをそれぞれ用意しておき、Figureインスタンスにデータを送り込みます。
描画したい数だけグラフの種類とデータを送り込めばよいので、p.line()をループしてやればOKです。
# 前行でインポートしている場合は不要
# from bokeh.plotting import figure, show
# サンプルデータを作成
x = [1, 2, 3, 4, 5]
y1 = [6, 7, 2, 4, 5]
y2 = [2, 3, 4, 5, 6]
y3 = [4, 5, 5, 7, 2]
# 後ほどループ文で描画するため、あらかじめリストに収めておく
y_list = [y1,y2,y3]
# 折れ線の色もリストに収めておく
col_list = ["blue", "red", "green"]
# 新しいプロットの作成
# タイトル、軸ラベルを決定し、figureインスタンスを立ち上げる
p = figure(title="Simple line example", x_axis_label='x', y_axis_label='y')
# 折れ線グラフを3本描画
# for文で複数変数を用いる場合、zip()でラップする必要がある
for y, col in zip(y_list, col_list):
p.line(x, y, legend_label="Temp.", color=col, line_width=2)
# 結果を描画する
show(p)

非常にカンタンにBokehでグラフを描画することが出来ました。
基本的には、XやYのリストを用意できれば、あとはFigure属性の各変数やline()の各変数を変更することでグラフをイイ感じに修正することができます。
たとえば、p.line()の部分を、p.stepにするとステップ関数になります。

少し変更が必要ですが、棒グラフもこの通り。
from bokeh.plotting import figure, show
# サンプルデータを作成
x = [1, 2, 3, 4, 5]
y = [6, 7, 2, 4, 5]
# 新しいプロットの作成
# タイトル、軸ラベルを決定し、figureインスタンスを立ち上げる
p = figure(title="Simple line example", x_axis_label='x', y_axis_label='y')
# 折れ線グラフのvbarを定義し、グラフ要素を決定する
p.vbar(x, top = y, legend_label="Temp.", width = 0.5)
# 結果を描画する
show(p)

まとめ
「Bokehを学ぶシリーズ」第1回はいかがでしたでしょうか。
まずはBokehの基本的な部分をなぞっただけですが、Bokehの良さをお伝えすることが出来たように思います。
経った数行でイイ感じのグラフを書くことが出来るBokehをマスターできれば、簡単に社内共有用のデータダッシュボードを作成することができそうです。
