グラフをWebページに埋め込んで、インタラクティブなWebアプリっぽくしたい。でもJavaScriptわからない。そんなときにBokehのembed.components
を使おう。
Bokehのバージョンは0.13.0を使っている。
bokeh.pydata.org
components
に描画するグラフのFigure
オブジェクトを渡すと、JavaScriptを記述したscript
タグとグラフ部分のdiv
タグがタプルとして返ってくる。
scirpt, div= components(plot)
手始めにBokehのQuickstartにある折れ線グラフを表示してみる。
bokeh.pydata.org
from bokeh.embed import components
from bokeh.plotting import figure
from flask import Flask, render_template
app = Flask(__name__)
def get_line_graph():
x = [1, 2, 3, 4, 5]
y = [6, 7, 2, 4, 5]
p = figure(title="simple line example", x_axis_label='x', y_axis_label='y')
p.line(x, y, legend="Temp.", line_width=2)
print(type(p))
return p
@app.route('/')
def index():
plot = get_line_graph()
script, div = components(plot)
return render_template('index.html', script=script, div=div)
<html>
<head>
<title>Flask Bokeh Sample</title>
<link rel="stylesheet" href="https://cdn.pydata.org/bokeh/release/bokeh-0.13.0.min.css" type="text/css" />
<link rel="stylesheet" href="https://cdn.pydata.org/bokeh/release/bokeh-widgets-0.13.0.min.css" type="text/css" />
<link rel="stylesheet" href="https://cdn.pydata.org/bokeh/release/bokeh-tables-0.13.0.min.css" type="text/css">
<script type="text/javascript" src="https://cdn.pydata.org/bokeh/release/bokeh-0.13.0.min.js"></script>
<script type="text/javascript" src="https://cdn.pydata.org/bokeh/release/bokeh-api-0.13.0.min.js"></script>
<script type="text/javascript" src="https://cdn.pydata.org/bokeh/release/bokeh-widgets-0.13.0.min.js"></script>
<script type="text/javascript" src="https://cdn.pydata.org/bokeh/release/bokeh-tables-0.13.0.min.js"></script>
</head>
<body>
<h1>Hello, Bokeh</h1>
{{ script|safe }}
{{ div|safe }}
</body>
</html>
Jinja2
のsafe
フィルタを使うことで、Flaskから渡した文字列をHTMLとして埋め込むことができる。テンプレートで気をつけておきたいのはCSSやJavaScriptをCDNから読み込むときのバージョン。Bokehの最新バージョンに合わせておこう。ここでは0.13.0
としている。
このStackOverFlowの回答を参考にしたが、動かなかったので試しにバージョンを最新にしたら動いた。
stackoverflow.com
さて、上記のコードを実行すると以下のようなWebページになる。動かせるし、ズームも保存もできる。
複数のグラフを埋め込むときはcomponents()
メソッドにFigure
オブジェクトが入ったタプルを渡す。すると、div
タグがタプルとして返ってくる。
以下、折れ線グラフに加えて散布図を埋め込んだ例。
from bokeh.embed import components
from bokeh.plotting import figure
from flask import Flask, render_template
import numpy as np
app = Flask(__name__)
def get_line_graph():
x = [1, 2, 3, 4, 5]
y = [6, 7, 2, 4, 5]
p = figure(title="simple line example", x_axis_label='x', y_axis_label='y')
p.line(x, y, legend="Temp.", line_width=2)
print(type(p))
return p
def get_scatter():
N = 4000
x = np.random.random(size=N) * 100
y = np.random.random(size=N) * 100
radii = np.random.random(size=N) * 1.5
colors = [
"#%02x%02x%02x" % (int(r), int(g), 150) for r, g in zip(50 + 2 * x, 30 + 2 * y)
]
TOOLS = "crosshair,pan,wheel_zoom,box_zoom,reset,box_select,lasso_select"
p = figure(tools=TOOLS, x_range=(0, 100), y_range=(0, 100))
p.circle(x, y, radius=radii, fill_color=colors, fill_alpha=0.6, line_color=None)
return p
@app.route('/')
def index():
line = get_line_graph()
scatter = get_scatter()
plots = (line, scatter)
script, div = components(plots)
return render_template('index.html', script=script, div=div)
<html>
<head>
<title>Flask Bokeh Sample</title>
<link rel="stylesheet" href="https://cdn.pydata.org/bokeh/release/bokeh-0.13.0.min.css" type="text/css" />
<link rel="stylesheet" href="https://cdn.pydata.org/bokeh/release/bokeh-widgets-0.13.0.min.css" type="text/css" />
<link rel="stylesheet" href="https://cdn.pydata.org/bokeh/release/bokeh-tables-0.13.0.min.css" type="text/css">
<script type="text/javascript" src="https://cdn.pydata.org/bokeh/release/bokeh-0.13.0.min.js"></script>
<script type="text/javascript" src="https://cdn.pydata.org/bokeh/release/bokeh-api-0.13.0.min.js"></script>
<script type="text/javascript" src="https://cdn.pydata.org/bokeh/release/bokeh-widgets-0.13.0.min.js"></script>
<script type="text/javascript" src="https://cdn.pydata.org/bokeh/release/bokeh-tables-0.13.0.min.js"></script>
</head>
<body>
<h1>Hello, Bokeh</h1>
{{ script|safe }}
{{ div.0|safe }}
{{ div.1|safe }}
</body>
</html>
以上、BokehのグラフをJavaScriptにしてWebページに埋め込む方法。
BokehのWidgets
を使うとダッシュボードめいたやつとか作れそう。
bokeh.pydata.org