Pythonのインタラクティブな可視化ライブラリBokehでグラフを描く

(2017-08-26)

Pythonの可視化というとmatplotlibや、 そのラッパーのseaborn、 データ解析ライブラリのPandasにもそういう機能があるけど、 これらが表示するのが静止画なのに対して、BokehはD3.jsで描画し、 拡大したりスクロールしたり、動的に何か表示することができる。Bokehはカメラのボケ。 似たようなのにPlotlyというのもあるけど、 こちらはPandasと同じpydata.orgドメインで、スターが多い。

jupyter/datascience-notebookイメージにもBokehがインストールされている。

$ docker run -d -p 8888:8888 jupyter/datascience-notebook start-notebook.sh

簡単なグラフを描く

output_notebookでJupytor Notebokに出力する。ファイルに出力する場合はouput_fileを呼ぶ。

from bokeh.plotting import figure
from bokeh.io import output_notebook, show
output_notebook()

figure()でplotするFigureオブジェクトを作成する。

p = figure(
    title="Hoge", 
    x_axis_label='x', 
    y_axis_label='y',
    y_axis_type="log"
)

line()で線をつないでcircle()で円を描く。

x = [0.1, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0]
y0 = [i**2 for i in x]
y1 = [10**i for i in x]
y2 = [10**(i**2) for i in x]

p.line(x, x, legend="y=x")
p.circle(x, x, legend="y=x", fill_color="white", size=8)

p.line(x, y0, legend="y=x^2", line_width=3)

p.line(x, y1, legend="y=10^x", line_color="red")
p.circle(x, y1, legend="y=10^x", fill_color="red", line_color="red", size=6)

p.line(x, y2, legend="y=10^x^2", line_color="orange", line_dash="4 4")

show(p)

折れ線グラフ

vbar()で 縦棒を描く。

x = [0.1, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0]

p.vbar(x, top=x, width=0.2, bottom=0, color="#CAB2D6")

show(p)

棒グラフ

annular_wedge()で弧を描く。

import math
from collections import namedtuple

Data = namedtuple('Data', ('name', 'value', 'color'))
rates = [Data("A", 0.6, "#7FC97F"), Data("B", 0.4, "#DD1C77")]

start_angle = 0

for rate in rates:
    p.annular_wedge(
            x=0, 
            y=0,
            inner_radius=0.2, 
            outer_radius=0.5, 
            start_angle=math.pi * 2 * start_angle, 
            end_angle=math.pi * 2 * (start_angle + rate.value),
            color=rate.color,
            legend=rate.name
    )
    start_angle += rate.value

show(p)

円グラフ

複数のグラフを連動させる

複数のfigureでrangeを合わせると連動する。

x = [0.1, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0]

left = figure(
    title="Left", 
    width=400,
    y_axis_type="log", 
    x_axis_label='x', 
    y_axis_label='y'
)

right = figure(
    title="Right", 
    width=400,
    x_range=left.x_range,
    x_axis_label='x', 
    y_axis_label='y'
)

left.line(x, x, legend="y=x")
right.line(x, x, legend="y=x")

p = gridplot([[left, right]])

show(p)

連動するグラフ

ホバーで情報を表示する

figureのtoolsにhoverを追加し、sourceにCoulumnDataSourceを渡して、 以下のようにselect_one(HoverTool)するとホバーで情報を表示できる。

import math
from bokeh.models import HoverTool, ColumnDataSource
from collections import namedtuple

p = figure(
    title="Hoge", 
    x_axis_label='x', 
    y_axis_label='y',
    tools="hover,save"
)

Data = namedtuple('Data', ('name', 'value', 'color'))
rates = [Data("A", 0.6, "#7FC97F"), Data("B", 0.4, "#DD1C77")]

start_angle = 0

for rate in rates:
    
    source = ColumnDataSource(
        data=dict(
            value=[rate.value],
        )
    )
    
    p.annular_wedge(
            x=0, 
            y=0,
            inner_radius=0.2, 
            outer_radius=0.5, 
            start_angle=math.pi * 2 * start_angle, 
            end_angle=math.pi * 2 * (start_angle + rate.value),
            color=rate.color,
            legend=rate.name,
            source=source
    )
    start_angle += rate.value

p.select_one(HoverTool).tooltips = [
    ("value", "@value")
]

show(p)

Tooltips