在Flask中嵌入bokeh图表

4

我希望通过Flask返回一个简单的线条bokeh图,但是当我浏览到localhost:5002/simpleline时,我得到的是:

('', ' ')

我有两个文件。Python文件:

from bokeh.plotting import figure, show, output_file
from bokeh.embed import components
from flask import Flask, render_template
app=Flask(__name__)

@app.route('/simpleline/')
def simpleLine():
    fig=figure(title="Sensor data")
    fig.line([1,2,3,4],[2,4,6,8])
    div=components(fig)
    return render_template('simpleline.html',div=div)
    show(fig)

if __name__ == "__main__":
    app.run(debug=True,port=5002)

而HTML模板为:

<!doctype html>
<html>
<head>
 <title>Figure examples</title>
 <link rel="stylesheet" href="http://cdn.bokeh.org/bokeh-0.7.1.min.css" type="text/css" />
 <script type="text/javascript"src="http://cdn.bokeh.org/bokeh-0.7.1.min.js"></script>
</head>
<body>
<div class='bokeh'>
 {{ div|safe }}
</div>
</body>
</html>

我相信我在这里缺少了一些基本的东西。

在mn的回答之后,发现components()会生成两个元素,一个Javascript字符串和一个html div。所以,我按照以下方式更新了我的脚本,但是这次网页显示为空白。

from bokeh.plotting import figure, show, output_file
from bokeh.embed import components
from flask import Flask, render_template
app=Flask(__name__)

@app.route('/simpleline/')
def simpleLine():
    fig=figure(title="Sensor data")
    fig.line([1,2,3,4],[2,4,6,8])
    global script
    global div
    script,div=components(fig)
    return render_template('simpleline.html',div=div,script=script)
    output_file("simpleline.html")
    show(fig)

fig=figure(title="Sensor data")
fig.line([1,2,3,4],[2,4,6,8])
script,div=components(fig)
if __name__ == "__main__":
    app.run(debug=True,port=5002)

而HTML模板如下:

<!doctype html>
<html>
 <head>
  <title>Figure examples</title>
  <link rel="stylesheet" href="http://cdn.bokeh.org/bokeh-0.9.0.min.css" type="text/css" />
  <script type="text/javascript" src="http://cdn.bokeh.org/bokeh-0.9.0.min.js"></script>
  {{ script|safe }}
 </head>
 <body>
  <div class='bokeh'>
   {{ div|safe }}
  </div>
 </body>
</html>

我尝试了所有的bokeh-0.7.1.min.js、0.9和0.10版本,但仍然得到同样的空白页面。
2个回答

7

components() 函数返回一个 (script, div) 元组,其中 <script> 包含绘图数据,伴随的 <div> 标签则用于加载绘图视图:

http://docs.bokeh.org/en/latest/docs/user_guide/embed.html#components

script, div = components(fig)
return render_template('simpleline.html',div=div, script=script)

模板
<!doctype html>
<html>
 <head>
  <title>Figure examples</title>
  <link rel="stylesheet" href="http://cdn.bokeh.org/bokeh/release/bokeh-0.10.0.min.css" type="text/css" />
  <script type="text/javascript" src="http://cdn.bokeh.org/bokeh/release/bokeh-0.10.0.min.js"></script>
  {{ script|safe }}
 </head>
 <body>
  <div class='bokeh'>
   {{ div|safe }}
  </div>
 </body>
</html>

现在事情清晰多了,谢谢!但是现在我得到了一个空白页面,不知道为什么。 - multigoodverse
尝试使用bokeh-0.10.0.min.js或0.9.0。 - r-m-n
还是一样的。如果有帮助,我更新了问题并添加了我目前拥有的脚本。 - multigoodverse
@mn,我又来打扰你了,能否请您解释一下外部JavaScript代码和由components()生成的代码之间的区别?它们有什么作用? - multigoodverse
1
外部代码是BokehJS库。由components()生成的代码包含您绘图所需的数据,并使用BokehJS进行绘图。 - r-m-n

2

如果你希望bokeh js和css自动加载,你可以使用autoload_static代替components。此外,你还可以将js保存到文件路径中,并仅在html中使用div来访问它。

这是我使用过的示例代码:

from bokeh.embed import autoload_static
from bokeh.resources import CDN
.............
.............
js, div = autoload_static(bar, CDN, '/static/bokeh/plot.js')
with open('static/bokeh/plot.js', 'w') as f:
        f.write(js)

在HTML文件中,只需包含
标签(包含JS脚本的路径)。
<!doctype html>
 <html>
   <head>
     <title>Figure examples</title>
   </head>
   <body>
    <div class='bokeh'>
    {{ div|safe }}
    </div>
   </body>
 </html>

当生成新的div id时,可能会出现缓存问题(除非刷新,否则不显示图形)。可以通过设置适当的缓存控制头 - 过期等或其他解决方法来管理。 - Aby

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接