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

如何通过Ajax在Flask中更新Bokeh图表(保留页面其他元素)

Flask+Bokeh同步更新:解决图表与表格联动问题

我来帮你搞定这个问题,先快速解决当前的核心需求(让图表和表格一起更新),再实现你想要的两个优化点——不用重绘整个图表、不需要额外模板。


一、快速解决:替换现有图表组件

你后端已经能生成新的Bokeh组件了,只需要在前端把旧的图表替换掉就行,步骤很简单:

1. 给图表容器加固定ID(修改index.html)

把原来渲染Bokeh的部分改成带固定ID的容器,方便后续定位替换:

<!-- 替换原来的{{ div_bok }} -->
<div id="bokeh-plot-wrapper">
    {{ div_bok }}
</div>
{{ script_bok }}

2. 前端AJAX回调里替换图表(添加JS逻辑)

假设你用jQuery处理表单提交,在index.html里加这段脚本(记得先引入jQuery):

$(document).ready(function() {
    $('#input_data_form').submit(function(e) {
        e.preventDefault();
        const nrow = $('#nrow').val();
        const ncol = $('#ncol').val();

        $.getJSON('/_get_table', {nrow, ncol}, function(res) {
            // 先更新表格(保留你原来的表格更新逻辑,比如DataTables的代码)
            $('#your-table-id').DataTable({
                destroy: true,
                data: res.my_table,
                columns: res.columns
            });

            // 然后更新Bokeh图表:替换容器内容+执行新脚本
            $('#bokeh-plot-wrapper').html(res.div_bok);
            // 先删掉旧的Bokeh脚本避免冲突,再插入新脚本
            $('script[id^="bokeh-"]').remove();
            const newScript = document.createElement('script');
            newScript.id = `bokeh-${Date.now()}`;
            newScript.innerHTML = res.script_bok;
            document.body.appendChild(newScript);
        });
    });
});

3. 后端代码暂时不用改

你当前的get_table视图已经返回了div_bok和script_bok,这部分先保留就行。


二、优化升级:仅更新图表数据(不重绘整个图表)

上面的方法能解决问题,但每次都重新生成整个图表组件有点浪费性能。更好的方式是用Bokeh的ColumnDataSource来做数据驱动更新,只传新数据,不用重新生成组件。

1. 后端初始化用ColumnDataSource(修改index视图)

把静态数据换成可更新的数据源,还要把数据源ID传给前端:

from bokeh.models import ColumnDataSource

@app.route('/')
def index():
    # 初始化可更新的数据源
    source = ColumnDataSource(data=dict(x=[1,2,3], y=[1,2,3]))
    p = figure(plot_width=150, plot_height=100)
    p.line('x', 'y', source=source)  # 绑定数据源到线条
    
    script_bok, div_bok = components(p)
    return render_template('index.html', 
                           div_bok=div_bok, 
                           script_bok=script_bok,
                           source_id=source.id)  # 把数据源ID传给前端

2. 后端接口只返回数据(修改get_table视图)

现在不需要生成新的图表组件,只返回表格数据和图表的新数据:

@app.route('/_get_table')
def get_table():
    nrow = request.args.get('nrow', type=int)
    ncol = request.args.get('ncol', type=int)
    
    # 生成表格数据(保留你原来的逻辑)
    df = pd.DataFrame(np.random.randint(0, 10, size=(nrow, ncol)))
    table_json = json.loads(df.to_json(orient="split"))
    
    # 生成图表需要的新数据(这里可以换成你实际的业务逻辑)
    new_plot_data = dict(
        x=list(range(nrow)),
        y=list(range(nrow))
    )
    
    return jsonify(
        my_table=table_json["data"],
        columns=[{"title": str(col)} for col in table_json["columns"]],
        plot_data=new_plot_data
    )

3. 前端用Bokeh API更新数据(修改JS逻辑)

利用Bokeh的JS API直接更新数据源,图表会自动刷新,不用替换整个组件:

<!-- 确保你已经引入了Bokeh的JS文件,你原来的head里已经有了 -->
<script src="http://cdn.bokeh.org/bokeh/release/bokeh-0.12.15.min.js"></script>
<script src="http://cdn.bokeh.org/bokeh/release/bokeh-widgets-0.12.15.min.js"></script>

<script>
$(document).ready(function() {
    // 拿到后端传过来的数据源ID
    const sourceId = "{{ source_id }}";
    // 获取Bokeh文档里的数据源对象
    const dataSource = Bokeh.documents[0].get_model_by_id(sourceId);

    $('#input_data_form').submit(function(e) {
        e.preventDefault();
        const nrow = $('#nrow').val();
        const ncol = $('#ncol').val();

        $.getJSON('/_get_table', {nrow, ncol}, function(res) {
            // 更新表格(保留你的原有逻辑)
            $('#your-table-id').DataTable({
                destroy: true,
                data: res.my_table,
                columns: res.columns
            });

            // 只更新图表数据,图表自动刷新!
            dataSource.data = res.plot_data;
            dataSource.change.emit(); // 触发数据更新事件
        });
    });
});
</script>

几个小提示

  • 注意Bokeh的JS版本要和后端版本一致(你用的是0.12.15,所以JS文件也要对应这个版本)。
  • 优化方案里,图表的样式、尺寸都不会变,只会更新数据,完全满足你的需求,而且不需要额外模板。
  • 如果你的Bokeh版本比较新,获取文档的方式可能是Bokeh.documents[0]或者Bokeh.embed.get_document(),不过0.12.15用前者没问题。

这样就能完美实现表格和图表的同步更新啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:32:03