bokeh とは
インタラクティブなデータ可視化ライブラリ
(参考:bokehを使ったデータ可視化例)
bokehのチュートリアル(First steps)のうち、必要そうな部分をまとめた。
Step 1-3. グラフの作成など
from bokeh.io import curdoc
from bokeh.plotting import figure, show
from bokeh.models import BoxAnnotation
from bokeh.models.tools import HoverTool
#データを準備する
x = [1, 2, 3, 4, 5]
y1 = [6, 7, 2, 4, 5]
y2 = [2, 3, 4, 5, 6]
y3 = [4, 5, 5, 7, 2]
# オブジェクトを作成
p = figure(title="Multiple glyphs example",x_axis_label="x", y_axis_label="y")
# 複数のグラフを描画する
line = p.line(x, y1, legend_label="Temp.", line_color="blue", line_width=2)
circle = p.circle(x, y3, legend_label="Objects", line_color="yellow", size=12)
# vbar = p.vbar(x=x, top=y2, legend_label="Rate", width=0.5, bottom=0, color="red")
# 判例を追加する
p.legend.location = "top_left"
#塗りつぶし
box = BoxAnnotation(bottom=2, top=4, left=1,right=3,fill_alpha=0.1, fill_color="red")
p.add_layout(box)
# 一度作成したグラフのプロパティを変更することも可能(散布図の塗りつぶしを青に変更してみる)
glyph = circle.glyph
glyph.fill_color = "blue"
# グラフを表示する
show(p)
Step 4. グラフをカスタマイズする
参考:step4
グラフテーマの変更
(参考:グラフテーマ一覧)
from bokeh.io import curdoc
from bokeh.plotting import figure, show
x = [1, 2, 3, 4, 5]
y = [4, 5, 5, 7, 2]
# グラフのテーマを変える。
# curdoc().theme = 'caliber'
curdoc().theme = "dark_minimal"
p = figure(sizing_mode="stretch_width", max_width=500, plot_height=250)
p.line(x, y)
show(p)
ツールの追加
from bokeh.models.tools import BoxZoomTool, PanTool, ResetTool
from bokeh.plotting import figure, show
# prepare some data
x = [1, 2, 3, 4, 5]
y = [4, 5, 5, 7, 2]
# create a plot
p = figure(
title="Modifying tools example",
tools=[BoxZoomTool(), ResetTool()],
sizing_mode="stretch_width",
max_width=500,
plot_height=250,
)
# ツールを追加する
p.add_tools(PanTool(dimensions="width"))
#toolbarの位置の変更
p.toolbar_location = "right"
# p.toolbar_location = None #非表示にしたい時
# p.toolbar.autohide = True #自動的に非表示にするかどうか。
# add a renderer
p.circle(x, y, size=10)
# show the results
show(p)
HoverToolを使う
マウスが特定のポイントに来た時に情報を表示する。
"@"を使用して、表示させたいデータのソース名を定義できる。
from bokeh.models.tools import HoverTool
from bokeh.plotting import figure, show
# prepare some data
x = [1, 2, 3, 4, 5]
y = [4, 5, 5, 7, 2]
p = figure(
y_range=(0, 10),
toolbar_location="right",
tools=[HoverTool()],
tooltips="Data point @x has the value @y",
sizing_mode="stretch_width",
max_width=500,
plot_height=250,
)
p.circle(x, y, size=10)
p.line(x, y, line_width=2)
show(p)
Step 5. グラフプロパティのベクトル化
データの値の大きさをグラフの色や大きさなどの性質に反映させる。
参考:step5
プロパティのリストを作成する方法
import numpy as np
from bokeh.plotting import figure, show
N = 1000
x = np.random.random(size=N) * 100
y = np.random.random(size=N) * 100
# yの大きさに応じた円の半径のリストを作成する。
radii = y / 100 * 2
# yの大きさに応じた色のリスト(rgb hex colors で表現)を作成する。
colors = ["#%02x%02x%02x" % (255, int(round(value * 255 / 100)), 255) for value in y]
# グラフ作成
p = figure(
title="Vectorized colors and radii example",
sizing_mode="stretch_width",
max_width=500,
plot_height=250,
)
# 散布図を作成(作成した、半径、色のリストを指定)
p.circle(
x,
y,
radius=radii,
fill_color=colors,
fill_alpha=0.6,
line_color="lightgrey",
)
show(p)
パレットを使用したカラーマッピング
Bokehには、あらかじめ定義された数多くのカラーパレットが用意されており、これを使ってデータに色をマッピングすることがでできる。
(カラーパレット一覧)
from bokeh.io import show
from bokeh.palettes import Turbo256
from bokeh.plotting import figure
from bokeh.transform import linear_cmap
x = list(range(-32, 33))
y = [i**2 for i in x]
# カラーマップを作成する。(使用するパレットや、データの最小・最大値を指定)
mapper = linear_cmap(field_name="y", palette=Turbo256, low=min(y), high=max(y))
# グラフを作成
p = figure(plot_width=500, plot_height=250)
# 散布図を作成し、colorに先ほど作成したカラーマップを指定する。
p.circle(x, y, color=mapper, size=10)
show(p)
Step 6. 複数プロットの描画
layoutメソッドやrowメソッド, gridplotメソッドを使う
参考:step6
from bokeh.layouts import row, layout, gridplot
from bokeh.plotting import figure, show
# prepare some data
x = list(range(11))
y0 = x
y1 = [10 - i for i in x]
y2 = [abs(i - 5) for i in x]
# create three plots with one renderer each
s1 = figure(plot_width=250, plot_height=250, background_fill_color="#fafafa")
s1.circle(x, y0, size=12, color="#53777a", alpha=0.8)
s2 = figure(plot_width=250, plot_height=250, background_fill_color="#fafafa")
s2.triangle(x, y1, size=12, color="#c02942", alpha=0.8)
s3 = figure(plot_width=250, plot_height=250, background_fill_color="#fafafa")
s3.square(x, y2, size=12, color="#d95b43", alpha=0.8)
s4 = figure(plot_width=250, plot_height=250, background_fill_color="#fafafa")
s4.square(x, y0, size=12, color="#d95b43", alpha=0.8)
# layoutメソッドを使う
show(layout([[s1, s2], [s3, s4]]))
# rowメソッドを使う
# show(row(s1, s2, s3))
# gridplotメソッド
# show(gridplot([[s1, s2],[s3, s4]]))
Step 7. 表示や出力
参考:step7
HTMLファイルに出力する
from bokeh.plotting import figure, output_file, save
x = [1, 2, 3, 4, 5]
y = [4, 5, 5, 7, 2]
# HTMLファイルに出力する場合
output_file(filename="custom_filename.html", title="Static HTML file")
p = figure(sizing_mode="stretch_width", max_width=500, plot_height=250)
circle = p.circle(x, y, fill_color="red", size=15)
# 結果をファイルに保存する
save(p)
Jupyter notebook上で表示する
output_notebook() を記載する。
from bokeh.plotting import figure, output_notebook
x = [1, 2, 3, 4, 5]
y = [4, 5, 5, 7, 2]
# HTMLファイルに出力する場合
output_notebook()
p = figure(sizing_mode="stretch_width", max_width=500, plot_height=250)
circle = p.circle(x, y, fill_color="red", size=15)
# 結果をJupyter Notebook上で表示する
show(p)
Step 8. データのフィルタリング
データにフィルターをかけて、特定のデータのみ表示できるようにする。
Bokeh独自のデータ構造(ColumnsDataSource)を経由して、データを描画する。
参考:Step8
from bokeh.layouts import gridplot
from bokeh.models import CDSView, ColumnDataSource, IndexFilter
from bokeh.plotting import figure, show
# 辞書からColumnDataSourceを作成する
source = ColumnDataSource(data=dict(x=[1, 2, 3, 4, 5], y=[1, 2, 3, 4, 5]))
#pandas dataFrameからColumnDataSourceを作成することも可能
# source = ColumnDataSource(df)
# インデックスでフィルターをかけた、データ(view)を作成
#(create a view using an IndexFilter with the index positions [0, 2, 4])
view = CDSView(source=source, filters=[IndexFilter([0, 2, 4])])
# 全てのデータを使ってプロット
p = figure(plot_height=300, plot_width=300)
p.circle(x="x", y="y", size=10, hover_color="red", source=source)
# フィルターをかけた特定のデータを使ってプロット(viewに先ほどのviewを渡す)
p_filtered = figure(plot_height=300, plot_width=300)
p_filtered.circle(x="x", y="y", size=10, hover_color="red", source=source, view=view)
show(gridplot([[p, p_filtered]]))
Step 9. ウィジェット(widget)の使用
プロットにインタラクティブなウィジェットを追加する。
グラフを操作して、描画する範囲やデータ、グラフのプロパティなどを動的に変化させることができる。
参考:step9
from bokeh.layouts import layout
from bokeh.models import Div, RangeSlider, Spinner
from bokeh.plotting import figure, show
x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
y = [4, 5, 5, 7, 2, 6, 4, 9, 1, 3]
# グラフ作成
p = figure(x_range=(1, 9), plot_width=500, plot_height=250)
points = p.circle(x=x, y=y, size=30, fill_color="#21a7df")
# テキストエリアとテキスト(HTML形式)を作成する(ウィジェットの説明用)
div = Div(
text="""
<p>Select the circle's size using this control element:</p>
""",
width=200,
height=30,
)
# spinner(数字を選択するウィジェット)
spinner = Spinner(title="Circle size",
low=0,
high=60,
step=5,
value=points.glyph.size, #初期値
width=200,
)
# スピナーによって生成された値をグリフのsizeプロパティにリンクさせるには、js_link()関数を使用する。
# この関数に渡す最初の引数は、
spinner.js_link("value", #円のglyphにリンクさせたいspinnerの属性(「value」)
points.glyph, # spinnerにリンクさせたいglyph(points.glyph)です。
"size" # spinnerの値にリンクさせたいglyphのプロパティです。
)
# RangeSlider(スライダーで範囲を選択するウィジェット)
# spinner と同様にオブジェクトを作成し、js_linkでつなぐ。
range_slider = RangeSlider(
title="Adjust x-axis range",
start=0,
end=10,
step=1,
value=(p.x_range.start, p.x_range.end),
)
range_slider.js_link("value", p.x_range, "start", attr_selector=0)
range_slider.js_link("value", p.x_range, "end", attr_selector=1)
# テキストエリア、ウィジェット、グラフのレイアウトを決める
layout = layout([
[div, spinner],
[range_slider],
[p],
])
show(layout)
参考
参考書籍
リンク
リンク
リンク