【Bokehを学ぶ-第4回】Bokehのグラフでツールバーを設定する!テーマを変更、軸の調整

Python

皆さん、こんにちは!

この記事はPythonのデータ可視化ライブラリである「Bokehを学ぶシリーズ」の第2回目。

公式ドキュメントのFirst Stepを更に詳しく解説するようなイメージで進めていきます。

朱莉
Bokehを使って、データ分析の結果を多くの人に共有しましょう!!

この記事では、第4回目ということで、公式ドキュメントのFirst Stepの1つ「Customizing your plot」の前半を解説していきます。

シリーズの別記事を以下にまとめておきます!

【Bokehを学ぶ-第1回】Bokehでインタラクティブな可視化を行おう! 折れ線グラフの描画

【Bokehを学ぶ-第2回】Bokehで複数種類のグラフを描画しよう

【Bokehを学ぶ-第3回】Bokehのグラフの細かい部分を整える 凡例、テキスト、注釈

プロット全体のカスタマイズ

プロット全体のカスタマイズでは、テーマ変更や、サイズに関する設定を行います。

テーマを変更する

テーマを使用すると、プロット全体を簡単に変更することができます。

個人的にはデフォルト設定で良いと思います…

ダークモードにした場合、グラフ以外の領域の色味などにも気を使う必要が出てくるため、簡単に描画できるBokehのメリットが薄れてしまうかなと感じますが、その辺はお好みです。

from bokeh.io import curdoc
from bokeh.plotting import figure, show

# サンプルデータを作成
# x,yをそれぞれリスト形式
x = [1, 2, 3, 4, 5]
y = [4, 5, 5, 7, 2]

# テーマを現在のドキュメントに適用する
curdoc().theme = "contrast" # caliber, dark_minimal, light_minimal, night_sky, and contrast.

# 新しいプロットの作成
p = figure(sizing_mode="stretch_width", max_width=500, height=250)

# 折れ線グラフを作成
p.line(x, y)

# 結果を描画する
show(p)

コントラスト(contrast)の場合(グラフの中身だけダークモード、軸や設定ツールなどの背景は白)

プロットのサイズ変更

次はプロットサイズです。

高さと幅を調整する機能で、多く利用する機能だと思います。

高さは「heigt」、幅は「width」で調整します。

from bokeh.plotting import figure, show

# サンプルデータを作成
# x,yをそれぞれリスト形式
x = [1, 2, 3, 4, 5]
y = [4, 5, 5, 7, 2]

# 新しいプロットを任意のサイズで作成する
p = figure(
    title="Plot sizing example",
    width=350,
    height=250,
    x_axis_label="x",
    y_axis_label="y",
)

# バブルチャートを作成
circle = p.circle(x, y, fill_color="red", size=15)

# 結果を描画する
show(p)

高さと幅も、あとから調整も可能です。(おそらく使わない)

from bokeh.plotting import figure, show

# サンプルデータを作成
# x,yをそれぞれリスト形式
x = [1, 2, 3, 4, 5]
y = [4, 5, 5, 7, 2]

# 新しいプロットを任意のサイズで作成する
p = figure(
    title="Plot resizing example",
    width=350,
    height=250,
    x_axis_label="x",
    y_axis_label="y",
)

# 定義したサイズを変更する
p.width = 450
p.height = 150

# バブルチャートを作成する
circle = p.circle(x, y, fill_color="red", size=15)

# 結果を描画する
show(p)

スマホに対応する(レスポンシブプロット)

次は画面(ウィンドウ)サイズによってサイズを自動調整するいわゆるレスポンシブ機能です。

sizing_mode 関数でレスポンシブモードを有効にできます。

stretch_widthで横をレスポンシブにできるので、その時は、Widthは指定する必要はありません。

from bokeh.plotting import figure, show

# サンプルデータを作成
# x,yをそれぞれリスト形式
x = [1, 2, 3, 4, 5]
y = [4, 5, 5, 7, 2]

# 新しいプロットをレスポンシブサイズで作成する
p = figure(
    title="Plot responsive sizing example",
    sizing_mode="stretch_width", # sizing_mode 関数でレスポンシブモードを有効にする
    height=250,
    x_axis_label="x",
    y_axis_label="y",
)

# バブルチャートを作成する
circle = p.circle(x, y, fill_color="red", size=15)

# 結果を描画する
show(p)

※画面を大きくした場合

※画面を細くした場合

軸のカスタマイズ

次は軸の微調整を行っていきます。

軸外観の定義

軸の見た目も色やフォントサイズなど様々な調整が可能です。

軸ラベルのテキストの修正は、「.axis_label」

軸の線幅の修正は、「axis_line_width」

軸の色の修正は、「axis_line_width」

軸の文字色は、「major_label_text_color」

軸のテキストの縦書き横書きは、「major_label_orientation」

で行います。

from bokeh.plotting import figure, show

# サンプルデータを作成
# x,yをそれぞれリスト形式
x = [1, 2, 3, 4, 5]
y = [4, 5, 5, 7, 2]

# 新しいプロットの作成
p = figure(
    title="Customized axes example",
    sizing_mode="stretch_width",
    max_width=500,
    height=350,
)

# バブルチャートを作成
p.circle(x, y, size=10)

# x軸を調整する
p.xaxis.axis_label = "Temp" # テキストを変更
p.xaxis.axis_line_width = 3 # 線幅の変更
p.xaxis.axis_line_color = "red" # 線色を変更

# y軸を調整する
p.yaxis.axis_label = "Pressure" # テキストを変更
p.yaxis.major_label_text_color = "orange" # 文字色を変更
p.yaxis.major_label_orientation = "vertical" # 文字の縦書き横書きを変更

# メモリの補助線の位置を修正する
# 軸線を中心として内側に何ピクセル(大きいと内側に食い込んだ形状)
p.axis.minor_tick_in = -3
# 軸線を中心として外側に何ピクセル(大きいと外側に伸びていく形状)
p.axis.minor_tick_out = 6

# 結果を描画する
show(p)

ちなみに、「minor_tick_in」と「minor_tick_out」は少し意味が分かりにくかったため、値を変更して試してみました。

主に軸の補助線の長さを調整するものだと考えれば良いと思います。

軸範囲の初期値を設定する

Bokehでは、グラフ内に描画されるすべての要素が含まれるように自動的に軸の初期値を設定します。

例えばAとB、複数のデータ群を比較したいときは、同じ軸の取り方でグラフを描画してほしいわけです。

この場合、ユーザー側で意図的に初期値を設定してやることで回避することが出来ます。

初期値の設定は、X軸なら「x_range」、Y軸なら「y_range」で設定可能です。

from bokeh.plotting import figure, show

# サンプルデータを作成
# x,yをそれぞれリスト形式
x = [1, 2, 3, 4, 5]
y = [4, 5, 5, 7, 2]

# 新しいプロットをレスポンシブで立ち上げる
# y軸の初期値を設定
p = figure(
    y_range=(0, 25),
    title="Axis range example",
    sizing_mode="stretch_width",
    max_width=500,
    height=250,
)

# バブルチャートを作成
circle = p.circle(x, y, size=8)

# 結果を描画する
show(p)

上の例では、y_rangeを0から25に設定することで、初期のY軸の最大値が25になっていることがわかります。

設定しない場合、おそらく最大値は10くらいになることが予想されますので、違いが判るかと思います。

軸の表示をカスタマイズ(単位を添える)

次は軸の表示のカスタマイズです。

以下の例のように、$マークや¥マークなどを書き加えて視認性をあげたい場合に用いると良いでしょう。

この操作を行うには、TickFormatterオブジェクト(特に数字+記号の場合は、「Numerical TickFormatter」)を用いて定義します。

使用にはインポートが必要です。

from bokeh.models import NumeralTickFormatter

インポート後はFigureformatに定義します。

p.yaxis[0].formatter = NumeralTickFormatter(format="$0.00")

from bokeh.models import NumeralTickFormatter
from bokeh.plotting import figure, show

# サンプルデータを作成
# x,yをそれぞれリスト形式
x = [1, 2, 3, 4, 5]
y = [4, 5, 5, 7, 2]

# 新しいプロットを定義
p = figure(
    title="Tick formatter example",
    sizing_mode="stretch_width",
    max_width=500,
    height=250,
)

# 軸のフォーマットを変更する
p.yaxis[0].formatter = NumeralTickFormatter(format="$0.00")

# バブルチャートと折れ線グラフを描画
p.circle(x, y, size=8)
p.line(x, y, color="navy", line_width=1)

# 結果を描画する
show(p)

適用できるformatを一部抜粋して掲載しておきます。

詳細は公式ドキュメントまで!

NUMBERS(数字):

Number(与えられる数字)Format(Bokehでの定義方法)String(実際の表示)
10000‘0,0.0000’10,000.0000
-10000‘0,0.0’-10,000.0
10000.1234‘0.000’10000.123
-0.23‘.00’-.23
1230974‘0.0a’1.2m
-104000‘0a’-104k
1‘0o’1st
23‘0o’23rd
1000o’100th

CURRENCY(通貨):

Number(与えられる数字)Format(Bokehでの定義方法)String(実際の表示)
1000.234‘$0,0.00’$1,000.23
1001‘$ 0,0[.]00’‘0b’$ 1,001
-1000.234‘$0.00’-$1000.23
1230974‘($ 0.00 a)’$ 1.23 m

BYTES(バイト):

Number(与えられる数字)Format(Bokehでの定義方法)String(実際の表示)
100‘0b’100B
7884486213‘0.0b’7.3GB
3467479682787‘0.000 b’3.154 TB

PERCENTAGES(パーセンテージ):

Number(与えられる数字)Format(Bokehでの定義方法)String(実際の表示)
1‘0%’100%
-0.43‘0 %’
-43 %

TIME(時刻):

Number(与えられる数字)Format(Bokehでの定義方法)String(実際の表示)
25‘00:00:00’0:00:25
63846‘00:00:00’17:44:06

対数軸の作成

軸を対数に変更することも可能です。

y_axis_typeを「log」にすることで、対数軸グラフの描画が可能です。

from bokeh.plotting import figure, show

# サンプルデータを作成
# x,yをそれぞれリスト形式
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]

# 新しいプロットを定義し、Y軸のタイプをログに変更
p = figure(
    title="Logarithmic axis example",
    sizing_mode="stretch_width",
    height=300,
    max_width=500,
    y_axis_type="log",
    y_range=[0.001, 10 ** 11],
    x_axis_label="sections",
    y_axis_label="particles",
)

# 各線を描画
p.line(x, x, legend_label="y=x")
p.circle(x, x, legend_label="y=x", fill_color="white", size=8)
p.line(x, y0, legend_label="y=x^2", line_width=3)
p.line(x, y1, legend_label="y=10^x", line_color="red")
p.circle(x, y1, legend_label="y=10^x", fill_color="red", line_color="red", size=6)
p.line(x, y2, legend_label="y=10^x^2", line_color="orange", line_dash="4 4")

# 結果を描画する
show(p)

X軸を日付に変更する

最後は、グラフの横軸を日付とする方法です。(縦軸でも可)

日付とするには、x_axis_typeを「datetime」にすることでOKです。

import random
from datetime import datetime, timedelta

from bokeh.models import DatetimeTickFormatter, NumeralTickFormatter
from bokeh.plotting import figure, show

# 日付のlistを作成 (today's date in subsequent weeks)
dates = [(datetime.now() + timedelta(day * 7)) for day in range(0, 26)]

# 25個のランダムデータを作成
y = random.sample(range(0, 100), 26)

# プロットを作成
p = figure(
    title="datetime axis example",
    x_axis_type="datetime",
    sizing_mode="stretch_width",
    max_width=500,
    height=250,
)

# バブルチャートと折れ線グラフを作成
p.circle(dates, y, size=8)
p.line(dates, y, color="navy", line_width=1)

# 軸のフォーマットを定義
p.yaxis[0].formatter = NumeralTickFormatter(format="$0.00")
p.xaxis[0].formatter = DatetimeTickFormatter(months="%b %Y")

# 結果を描画する
show(p)

まとめ

「Bokehを学ぶシリーズ」第4回はいかがでしたでしょうか。

まずはBokehは簡単にデータを可視化出来るだけでなく、かゆいところに手が届く非常に優秀なライブラリです。

経った数行でイイ感じのグラフを書くことが出来るBokehをマスターできれば、簡単に社内共有用のデータダッシュボードを作成することができそうです。

朱莉
このシリーズを通じて、データ可視化をより効率的に行えるようになれば嬉しいです!