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

python

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="logging"
)

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="logging", 
    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)