Bokehでちょっとイマドキな感じのチャートを描く
最近よくこんな感じのチャート見かけるじゃないですか。これをBokehで描いてみようと思います。
まず必要なモジュールをインポートします。
import requests
import pandas as pd
from bokeh.plotting import figure
from bokeh.models import ColumnDataSource, HoverTool, CrosshairTool, NumeralTickFormatter
from bokeh.io import show
データはCryptoCompareのAPIを使います。OHLCデータが取れる物を使ってそれをpandas.DataFrameに入れて、Bokeh描画用のデータとしてColumnDataSourceにセットします。
# データ準備
data = requests.get("https://min-api.cryptocompare.com/data/v2/histoday?fsym=BTC&tsym=JPY&limit=150")
df = pd.DataFrame(data.json()["Data"]["Data"])
df["time"] = pd.to_datetime(df["time"], unit="s")
# Bokeh描画用データ
source = ColumnDataSource(df)
以下、描画していきます。メインチャートとしてエリアチャートを描画し、そこに吹き出しをつけています。Bokehの吹き出しはデフォルトだと矢印が付いているので、それをOFFにします。
# 描画レイアウト
p = figure(
title="BTC/JPY Close Price",
plot_width=1500,
plot_height=400,
x_axis_type="datetime"
)
# メインチャート
p.varea(
x="time",
y1="close",
y2=0,
source=source,
alpha=0.5
)
# 吹き出し
hover = HoverTool(
tooltips=[
("Date", "@time{%F}"),
("Close", "@close{0,0}")
],
formatters={"time": "datetime"},
mode="vline",
show_arrow=False, # 矢印を消します
)
p.add_tools(hover)
次にマウスの位置に●と縦棒を表示します。ちょっと面倒ですが、circle自体は全ての日付のポイントに描画されているのですが、colorをNone指定して表示させず、マウスオーバーされた時のみ●が表示されるようにしています。
# マウスの位置に合わせて●を表示
r_circle = p.circle(
x="time",
y="close",
source=source,
color=None, # マウスの位置だけ表示するので基本は非表示
hover_alpha=0.8,
line_color=None,
hover_line_color=None,
size=8
)
# マウスの位置だけ表示
hover_circle = HoverTool(
tooltips=None,
renderers=[r_circle],
mode="vline"
)
p.add_tools(hover_circle)
# マウスの位置に縦棒を表示
cross_hair = CrosshairTool(
dimensions="height",
line_alpha=0.2
)
p.add_tools(cross_hair)
最後に細かいところの整形をして表示します。
# y軸の数字フォーマット
p.yaxis[0].formatter = NumeralTickFormatter(format="0,0")
# 背景グリッドの線を消す
p.xgrid.grid_line_color = None
p.ygrid.grid_line_color = None
# 表示
show(p)
こんな感じなりました。
ソースコードはこちらです。