You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改代码实现Flask多路由部署多个Bokeh Server绘图?

解决Flask多路由嵌入不同Bokeh绘图的问题

我帮你梳理下问题:你在原有Flask+Bokeh整合的代码基础上添加了/plot路由后程序崩溃,大概率是因为没有正确在Bokeh Server中注册第二个绘图应用,或者路由引用的路径配置有误。下面是针对你使用的Bokeh 0.12.14版本的完整解决方案:

核心思路

要在不同Flask路由展示不同Bokeh绘图,需要做到两点:

  1. 在Bokeh Server中注册独立的Bokeh应用(每个绘图对应一个应用)
  2. 每个Flask路由生成对应Bokeh应用的嵌入脚本,指向正确的Bokeh Server路径

完整代码示例

1. Flask主文件(比如app.py)

from flask import Flask, render_template
from bokeh.embed import server_document
from bokeh.server.server import Server
from tornado.ioloop import IOLoop
from threading import Thread

app = Flask(__name__)

# --- 第一个绘图:主页面的绘图 ---
def modify_doc_main(doc):
    from bokeh.plotting import figure
    from bokeh.models import ColumnDataSource
    
    # 这里写你原来的modify_doc绘图逻辑
    source = ColumnDataSource(data=dict(x=[1, 2, 3], y=[4, 5, 6]))
    p = figure(title="主页面绘图")
    p.circle(x='x', y='y', source=source, size=10, color="navy")
    
    doc.add_root(p)

# --- 第二个绘图:/plot路由的网格绘图 ---
def modify_doc_grid(doc):
    from bokeh.layouts import gridplot
    from bokeh.plotting import figure
    
    # 这里写你的网格绘图逻辑
    p1 = figure(plot_width=250, plot_height=250, title="图1")
    p1.circle([1, 2, 3], [4, 5, 6], color="red")
    
    p2 = figure(plot_width=250, plot_height=250, title="图2")
    p2.line([1, 2, 3], [6, 5, 4], color="green")
    
    p3 = figure(plot_width=250, plot_height=250, title="图3")
    p3.square([1, 2, 3], [5, 3, 4], color="orange")
    
    # 创建网格布局
    grid = gridplot([[p1, p2], [p3, None]])
    doc.add_root(grid)

# --- 启动Bokeh Server的线程 ---
def bokeh_server_worker():
    # 注册两个Bokeh应用,分别对应不同路径
    server = Server(
        {
            '/main_app': modify_doc_main,
            '/grid_app': modify_doc_grid
        },
        io_loop=IOLoop(),
        # 必须包含Flask的运行地址,否则WebSocket连接会被拒绝
        allow_websocket_origin=["localhost:8000"]
    )
    server.start()
    server.io_loop.start()

# --- Flask路由 ---
@app.route('/')
def main_page():
    # 生成指向Bokeh Server中/main_app的嵌入脚本
    script = server_document('http://localhost:5006/main_app')
    return render_template("embed.html", script=script)

@app.route('/plot')
def grid_plot_page():
    # 生成指向Bokeh Server中/grid_app的嵌入脚本
    script = server_document('http://localhost:5006/grid_app')
    return render_template("embed.html", script=script)

if __name__ == '__main__':
    # 启动Bokeh Server线程
    Thread(target=bokeh_server_worker).start()
    # 启动Flask服务,端口8000(和Bokeh Server的5006区分开)
    app.run(port=8000, debug=True)

2. 模板文件(templates/embed.html)

在项目根目录创建templates文件夹,放入下面的模板:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Bokeh绘图展示</title>
    {{ script|safe }}
</head>
<body>
    <!-- Bokeh绘图会自动渲染在这里 -->
</body>
</html>

关键注意事项(避免崩溃的核心)

  • Bokeh Server应用注册:每个绘图必须对应一个独立的modify_doc函数,并且在Server中注册不同的路径(比如/main_app和/grid_app),不能重复路径。
  • 跨域配置:allow_websocket_origin必须包含Flask的运行地址(比如localhost:8000),否则Bokeh的实时交互连接会被拒绝,导致页面崩溃。
  • 端口区分:Bokeh Server默认用5006端口,Flask用8000,避免端口冲突。

可选:静态绘图嵌入(无需Bokeh Server)

如果你的绘图不需要动态交互(比如滑块、按钮),可以用components函数生成静态片段,不需要启动Bokeh Server线程,更轻量:

from flask import Flask, render_template
from bokeh.embed import components
from bokeh.plotting import figure
from bokeh.layouts import gridplot

app = Flask(__name__)

@app.route('/')
def static_main():
    p = figure(title="静态主绘图")
    p.circle([1,2,3], [4,5,6])
    script, div = components(p)
    return render_template("static_embed.html", script=script, div=div)

@app.route('/plot')
def static_grid():
    p1 = figure(plot_width=200, plot_height=200)
    p1.circle([1,2,3], [4,5,6])
    p2 = figure(plot_width=200, plot_height=200)
    p2.line([1,2,3], [6,5,4])
    grid = gridplot([[p1,p2]])
    script, div = components(grid)
    return render_template("static_embed.html", script=script, div=div)

if __name__ == '__main__':
    app.run(port=8000, debug=True)

对应的static_embed.html模板需要引入Bokeh的CSS和JS:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>静态Bokeh绘图</title>
    <link rel="stylesheet" href="https://cdn.bokeh.org/bokeh/release/bokeh-0.12.14.min.css" type="text/css" />
    <script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-0.12.14.min.js"></script>
    {{ script|safe }}
</head>
<body>
    {{ div|safe }}
</body>
</html>

内容的提问来源于stack exchange,提问作者machump

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 10:33:05