皆さん、こんにちは!
この記事はPythonのデータ可視化ライブラリである「Bokehを学ぶシリーズ」の第7回目。
公式ドキュメントのFirst Stepを更に詳しく解説するようなイメージで進めていきます。


この記事では、第5回目ということで、公式ドキュメントのFirst Stepの1つ「Combining plots」の後半を解説していきます。
シリーズの別記事を以下にまとめておきます!
グラフの複数表示(行と列)
これまでの記事では1つのグラフに対して様々なカスタマイズを行ってきました。
この記事では、カスタマイズが終わり完成したグラフを、Webページに配置していく作業を行います。
まずは、シンプルにグラフを横一列(または縦一列)に配置します。
水平方向の場合はrow()をインポート、垂直の場合column()をインポートします。
描画にはshow()関数を使い、内部にrow()を挿入すれば複数のグラフオブジェクトを表示することが可能です。
from bokeh.layouts import row
from bokeh.plotting import figure, show
# データセットを作成
x = list(range(11))
y0 = x
y1 = [10 - i for i in x]
y2 = [abs(i - 5) for i in x]
# 3つのプロットを作成
s1 = figure(width=250, height=250, background_fill_color="#fafafa")
s1.circle(x, y0, size=12, color="#53777a", alpha=0.8)
s2 = figure(width=250, height=250, background_fill_color="#fafafa")
s2.triangle(x, y1, size=12, color="#c02942", alpha=0.8)
s3 = figure(width=250, height=250, background_fill_color="#fafafa")
s3.square(x, y2, size=12, color="#d95b43", alpha=0.8)
# プロットを1列に配置する
show(row(s1, s2, s3))

上記の例では、グラフサイズを完全に固定していますが、レスポンシブとすることも可能です。
基本的にユーザー側の画面サイズは不明なので、レスポンシブで良いと思います。
レスポンシブ対応とする場合は、show()関数内にsizing_mode を設定します。
from bokeh.layouts import row
from bokeh.plotting import figure, show
# データセットを作成
x = list(range(11))
y0 = x
y1 = [10 - i for i in x]
y2 = [abs(i - 5) for i in x]
# 3つのプロットを作成
s1 = figure(width=250, height=250, background_fill_color="#fafafa")
s1.circle(x, y0, size=12, color="#53777a", alpha=0.8)
s2 = figure(width=250, height=250, background_fill_color="#fafafa")
s2.triangle(x, y1, size=12, color="#c02942", alpha=0.8)
s3 = figure(width=150, height=250, background_fill_color="#fafafa")
s3.square(x, y2, size=12, color="#d95b43", alpha=0.8)
# プロットを1行に配置
# 横のサイズを可変にする(レスポンシブ)
show(row(children=[s1, s2, s3], sizing_mode="scale_width"))

グラフの複数表示(グリッド)
from bokeh.io import output_file, show
from bokeh.layouts import gridplot
from bokeh.plotting import figure
output_file("layout_grid.html")
# データセットを作成
x = list(range(11))
y0 = x
y1 = [10 - i for i in x]
y2 = [abs(i - 5) for i in x]
# 3つのプロット(figure)を作成
s1 = figure(background_fill_color="#fafafa")
s1.circle(x, y0, size=12, alpha=0.8, color="#53777a")
s2 = figure(background_fill_color="#fafafa")
s2.triangle(x, y1, size=12, alpha=0.8, color="#c02942")
s3 = figure(background_fill_color="#fafafa")
s3.square(x, y2, size=12, alpha=0.8, color="#d95b43")
# ”グリッド”オブジェクトにグラフを定義
grid = gridplot([[s1, s2], [None, s3]], width=250, height=250)
# グリッドを表示
show(grid)

テーブルの追加
次はチュートリアルには含まれていませんが、テーブル要素を作成してみます。
BokehはSkuckGridに基づく洗礼されたデータテーブル要素が提供されています。
Bokehのデフォルトで、ヘッダーやインデックス、グラフのソートにも対応しているのでかなりリッチですが、コードの記述には少し癖があります。
テーブルデータを描画するためには、DataTableオブジェクトが必要になります。
DataTableに含まれる要素は、データ本体と列名です。(幅や高さは任意)
データ本体はdict型となっていますが、いわゆるデータフレームを直接入れることも可能です。
source = ColumnDataSource(df)
ただし、列名は個別にTableColumnを定義する必要があります。
一般的にデータフレームを全て表示させることも珍しいと思われますので、そこまで問題ないと思います。
from datetime import date
from random import randint
from bokeh.io import show
from bokeh.models import ColumnDataSource, DataTable, DateFormatter, TableColumn
# データセットを用意
data = dict(
dates=[date(2014, 3, i+1) for i in range(10)],
users = [randint(200, 500) for i in range(10)],
downloads=[randint(0, 100) for i in range(10)]
)
# データソースとして定義する
source = ColumnDataSource(data)
# 列を定義する(リスト形式にTableColumn要素を作成)
columns = [
TableColumn(field="dates", title="Date", formatter=DateFormatter()),
TableColumn(field="users", title="Users"),
TableColumn(field="downloads", title="Downloads"),
]
# テーブルオブジェクトを作成
data_table = DataTable(source=source, columns=columns, width=400, height=280)
# テーブルを描画
show(data_table)
# グラフ作成のサンプルコード http://docs.bokeh.org/en/latest/docs/user_guide/interaction/widgets.html

各列をクリックすると、その列でソートが可能です。(以下はUsers列を昇順にソート)

まとめ
「Bokehを学ぶシリーズ」第7回はいかがでしたでしょうか。
いよいよグラフを複数表示させ、テーブルの作成方法も学びました。
ここまで様々なグラフの表示方法やカスタマイズ方法を学んできましたが、いよいよBokehでダッシュボードが作成できそうになってきましたね。
