Flask 服务器 运行 Bokeh 应用程序:如何从 server_document() 函数生成的脚本访问绘图
Flask server running Bokeh app: how to access plots from a script generated by server_document() function
我一直在使用 Bokeh 来绘制大型数据库,并使用 Flask 在本地主机上为应用程序提供服务。总结代码如下所示:
app = Flask(__name__)
def make_doc(doc):
def plot_time():
p = figure(plot_height=400, plot_width=1000, tools="xpan,box_zoom,xwheel_zoom,reset,save",
x_axis_type="datetime", background_fill_color="#efefef",outline_line_color="#000000")
for us,color in zip(lista_plots,colors):
p.line(x="Instant", y=us, source=source, name=us, line_color=color, line_width=1, legend=us.title())
return p
def plot_time_aux():
p = figure(plot_height=115, plot_width=1000, x_axis_type="datetime", y_axis_type=None, tools="", background_fill_color="#efefef")
for us in list_plots:
p.line(x="Instant", y=us, source=source, name=us, line_color="gray", alpha=0.55)
return p
p1 = plot_time()
p2 = plot_time_aux()
doc.add_root(p1)
doc.add_root(p2)
doc.title = "Time Plot"
@app.route('/', methods=['GET'])
def bkapp_page():
script = server_document('http://localhost:5006/bkapp')
return render_template("index.html", script=script)
def bk_worker():
server = Server({'/bkapp': make_doc}, io_loop=IOLoop(), allow_websocket_origin=["localhost:{}".format(port)])
server.start()
server.io_loop.start()
from threading import Thread
Thread(target=bk_worker).start()
if __name__ == '__main__':
print('Opening single process Flask app with embedded Bokeh application on http://localhost:{}/'.format(port))
webbrowser.open_new("http://localhost:{}/".format(port))
app.run(port=port, debug=False)
代码运行得很好,但是当谈到访问 p1 和 p2 以将其插入 Jinja2 html 模板中的自定义 div 时,我不知道如何做。 html 模板如下所示:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Time Plots</title>
</head>
<body>
{% for root in script.roots %}
<div>{{ embed(root) }}</div>
{% endfor %}
{{ script | safe }}
</body>
</html>
实际上,脚本一个接一个地绘制 p1 和 p2,只是忽略了 Jinja2 for 循环(可能是因为我在模板中引用的变量不'存在...)。但是,我想将每个图(p1 和 p2)作为 render_template() 函数中的参数传递,这样我就可以自由地将它们放在 html 模板上的任何位置,但是我不知道怎么做。
欢迎提出任何想法。
我将概述如何实现多图:
为每个绘图创建单独的 Bokeh 应用程序。参考 modify_doc
在 example
def change_doc1():
# code to define how plot 1 should behave
def change_doc2():
# code to define how plot 2 should behave
使用多个应用程序而不是单个应用程序初始化 Bokeh 服务器
def bk_worker():
plots = { "/plot1": change_doc1, "/plot2": change_doc2 }
server = Server(plots, io_loop=IOLoop(), allow_websocket_origin=["localhost:{}".format(port)])
server.start()
server.io_loop.start()
- 在Flask路由中单独获取scrtips,发送到模板中。
@app.route('/', methods=['GET'])
def bkapp_page():
script1 = server_document('http://localhost:5006/plot1')
script2 = server_document('http://localhost:5006/plot2')
return render_template("embed.html", script1=script1, script2=script2)
- 单独使用模板中的脚本并将其放置在 HTML 中您想要的位置
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Time Plots</title>
</head>
<body>
<div id="plot1">
{{ script1 | safe }}
</div>
<div id="plot2">
{{ script2 | safe }}
</div>
</body>
</html>
我一直在使用 Bokeh 来绘制大型数据库,并使用 Flask 在本地主机上为应用程序提供服务。总结代码如下所示:
app = Flask(__name__)
def make_doc(doc):
def plot_time():
p = figure(plot_height=400, plot_width=1000, tools="xpan,box_zoom,xwheel_zoom,reset,save",
x_axis_type="datetime", background_fill_color="#efefef",outline_line_color="#000000")
for us,color in zip(lista_plots,colors):
p.line(x="Instant", y=us, source=source, name=us, line_color=color, line_width=1, legend=us.title())
return p
def plot_time_aux():
p = figure(plot_height=115, plot_width=1000, x_axis_type="datetime", y_axis_type=None, tools="", background_fill_color="#efefef")
for us in list_plots:
p.line(x="Instant", y=us, source=source, name=us, line_color="gray", alpha=0.55)
return p
p1 = plot_time()
p2 = plot_time_aux()
doc.add_root(p1)
doc.add_root(p2)
doc.title = "Time Plot"
@app.route('/', methods=['GET'])
def bkapp_page():
script = server_document('http://localhost:5006/bkapp')
return render_template("index.html", script=script)
def bk_worker():
server = Server({'/bkapp': make_doc}, io_loop=IOLoop(), allow_websocket_origin=["localhost:{}".format(port)])
server.start()
server.io_loop.start()
from threading import Thread
Thread(target=bk_worker).start()
if __name__ == '__main__':
print('Opening single process Flask app with embedded Bokeh application on http://localhost:{}/'.format(port))
webbrowser.open_new("http://localhost:{}/".format(port))
app.run(port=port, debug=False)
代码运行得很好,但是当谈到访问 p1 和 p2 以将其插入 Jinja2 html 模板中的自定义 div 时,我不知道如何做。 html 模板如下所示:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Time Plots</title>
</head>
<body>
{% for root in script.roots %}
<div>{{ embed(root) }}</div>
{% endfor %}
{{ script | safe }}
</body>
</html>
实际上,脚本一个接一个地绘制 p1 和 p2,只是忽略了 Jinja2 for 循环(可能是因为我在模板中引用的变量不'存在...)。但是,我想将每个图(p1 和 p2)作为 render_template() 函数中的参数传递,这样我就可以自由地将它们放在 html 模板上的任何位置,但是我不知道怎么做。
欢迎提出任何想法。
我将概述如何实现多图:
为每个绘图创建单独的 Bokeh 应用程序。参考
modify_doc
在 exampledef change_doc1(): # code to define how plot 1 should behave def change_doc2(): # code to define how plot 2 should behave
使用多个应用程序而不是单个应用程序初始化 Bokeh 服务器
def bk_worker(): plots = { "/plot1": change_doc1, "/plot2": change_doc2 } server = Server(plots, io_loop=IOLoop(), allow_websocket_origin=["localhost:{}".format(port)]) server.start() server.io_loop.start()
- 在Flask路由中单独获取scrtips,发送到模板中。
@app.route('/', methods=['GET']) def bkapp_page(): script1 = server_document('http://localhost:5006/plot1') script2 = server_document('http://localhost:5006/plot2') return render_template("embed.html", script1=script1, script2=script2)
- 单独使用模板中的脚本并将其放置在 HTML 中您想要的位置
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>Time Plots</title> </head> <body> <div id="plot1"> {{ script1 | safe }} </div> <div id="plot2"> {{ script2 | safe }} </div> </body> </html>