Flask Web应用中Bokeh图表旁多余文本的去除方案
问题成因及解决方案
问题成因
我帮你排查了下,出现多余代码文本主要是两个原因:
- 模板结构嵌套错误:你的模板继承了
base.html,但在{% block content %}里又重复写了<html>、<head>、<body>标签。一般来说base.html已经包含了这些页面根结构,嵌套后会导致浏览器解析异常,把部分未正确识别的代码当成文本显示出来。 - Bokeh Components使用不当:你已经用
column(slider, plot)组合好了完整布局,但调用components()时却传入了一个包含独立plot和新创建的column(slider)的字典,这会生成冗余的组件定义代码,而且没有利用好已经组合好的布局,最终导致页面出现多余的代码文本。
解决方案
1. 修改Python代码,正确传递Bokeh布局
直接把组合好的完整布局传给components(),而不是分开传递单个组件:
@app.route('/graph') def graph(): x = [x*0.005 for x in range(0, 200)] y = x source = ColumnDataSource(data=dict(x=x, y=y)) plot = figure(plot_width=400, plot_height=400) plot.line('x', 'y', source=source, line_width=3, line_alpha=0.6) callback = CustomJS(args=dict(source=source), code=""" var data = source.data; var f = cb_obj.value var x = data['x'] var y = data['y'] for (var i = 0; i < x.length; i++) { y[i] = Math.pow(x[i], f) } source.change.emit(); """) slider = Slider(start=0.1, end=4, value=1, step=.1, title="power") slider.js_on_change('value', callback) # 保留组合好的布局 layout = column(slider, plot) # 将整个布局传入components,生成对应的script和div script, div = components(layout) kwargs = {'script': script, 'div': div, 'title': 'bokeh-with-flask'} return render_template('graph.html', **kwargs)
2. 修复HTML模板结构,移除嵌套的根标签
去掉{% block content %}里的<html>、<head>、<body>,把Bokeh的资源引用放到合适的位置(比如利用base.html的head和scripts扩展块):
{% extends "base.html" %} {% block head %} {{ super() }} <link href="https://cdnjs.cloudflare.com/ajax/libs/bokeh/1.2.0/bokeh.min.css" rel="stylesheet" type="text/css"> <link href="https://cdnjs.cloudflare.com/ajax/libs/bokeh/1.2.0/bokeh-widgets.css" rel="stylesheet" type="text/css"> <link href="https://cdnjs.cloudflare.com/ajax/libs/bokeh/1.2.0/bokeh-tables.css" rel="stylesheet" type="text/css"> {% endblock %} {% block content %} <h1>Chart</h1> {{ div|safe }} {{ script|safe }} {% endblock %} {% block scripts %} {{ super() }} <script src="https://cdnjs.cloudflare.com/ajax/libs/bokeh/1.2.0/bokeh.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/bokeh/1.2.0/bokeh-widgets.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/bokeh/1.2.0/bokeh-tables.js"></script> {% endblock %}
注:
{{ super() }}用来保留base.html中原有的head和scripts内容,如果你的base.html没有定义这些扩展块,也可以把CSS和JS放在content块的末尾,但绝对不要嵌套<html>、<head>、<body>标签。
这样修改后,页面结构会被正确解析,Bokeh的组件代码也不会冗余,多余的文本就会消失,同时滑块的交互功能依然正常。
内容的提问来源于stack exchange,提问作者alexnesov
相关产品推荐
相关产品推荐

