Flask + Bokeh AjaxDataSource [英] Flask + Bokeh AjaxDataSource

查看:334
本文介绍了Flask + Bokeh AjaxDataSource的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用Flask + Bokeh挣扎AjaxDataSource:

我有一个返回json数据的函数:

<$ p $
$ b $全局x,y
x = x + 0.1
y = math.sin(x)
return flask.jsonify(x = [x],y = [y])

我可以使用它与一个Bokeh AjaxDataSource没有问题来创建一个流式图:

 p = figure()
p.line('x' ,'y',source = source)
show(p)

尝试将其嵌入到一个页面中,AjaxDataSource不会查询服务器。剧情无法呈现没有错误。请注意,如果我使用的是静态图而不是AjaxDataSource,那么它的绘图效果很好。以下是相关的代码:

  template = Template('''<!DOCTYPE html> 
< html lang =en>
< head>
< meta charset =utf-8>
< title> Streaming Example< / title>
{
{{plot_script}} $ b $ {bs} b $ lt; / body>
< / html>
''')

@ app.route(/)
def simple():
streaming = True
source = AjaxDataSource(data_url =http:// localhost:5000 / data,
polling_interval = 1000,mode ='append')

(b)b















$ b $ css_resources = INLINE.render_css()

脚本,div =组件(图,内联)

html = template.render(
p lot_script = script,
plot_div = div,
js_resources = js_resources,
css_resources = css_resources


返回encode_utf8(html)

如果有人有任何想法,我会很感激。



完成的可运行代码示例。花了几分钟的时间来重现所有缺少的必要的输入,因为一旦有一个可运行的脚本,只需几秒钟就诊断出来。



最近有些BokehJS代码路径变得更加严格了,几乎在每个实例中都很好,这留下了一个与 AjaxDataSource 没有被注意到的不良交互。当我运行示例时,我确实在浏览器中看到错误: JS控制台:

 错误:尝试检索不存在的字段'x'的属性数组

这是workround的关键,它是只是为了确保数据源对于 x y 具有(空)列:

  source.data = dict(x = [],y = [])

下面有一个完整的工作脚本。我想请您在 Bokeh问题跟踪器上提供相关信息,以便这样做错误可以优先和固定






  from flask import烧瓶,jsonify 
from jinja2导入模板
导入数学

from bokeh.plotting导入数据
from bokeh.models导入AjaxDataSource
from bokeh.embed导入组件
from bokeh.resources从bokeh.util.string导入INLINE
encode_utf8

$ b app = Flask(__ name__)
$ b $,y = 0,0

@ app.route(/ data,methods = ['POST'])
def get_x():
全局x,y
x = x + 0.1
y = math.sin(x)
return jsonify(x = [x],y = [y])

template = Template('''<!DOCTYPE html> ;
< html lang =en>
< head>
< meta charset =utf-8>
< title> / title>
{{js_resources}}
{{css_resources}}
< / head>
< body>
{{plot_div}}
{{plot_script}}
< / body>
< / html>


@ app.route(/)
def simple():
streaming = True
source = AjaxDataSource(data_url =http:// localhost:5000 / data,
polling_interval = 1000,mode ='append')

source.data = dict(x = [],y = [] )







$ b $ s















$ b $ INLINE.render_js()
css_resources = INLINE.render_css()

脚本,div =组件(图,内联)

html = template.render(
plot_script = script,
plot_div = div,
js_resources = js_resources,
css_resources = css_resources


encode_utf8(html)

app.run(debug = True)


Struggling with Flask + Bokeh AjaxDataSource:

I have a function that returns json data:

@app.route("/data", methods=['POST'])
def get_x():
    global x, y
    x = x + 0.1
    y = math.sin(x)
    return flask.jsonify(x=[x], y=[y])

I can use use it with a Bokeh AjaxDataSource no problem to create a streaming plot:

source = AjaxDataSource(data_url="http://localhost:5000/data", polling_interval=1000, mode='append')
p = figure()
p.line('x', 'y', source=source)                                                                       
show(p)

However, when I try to embed this in a flask page, the AjaxDataSource does not query the server. The plot fails to render with no errors. Note that if I use a static plot instead of an AjaxDataSource, it plots fine. Here's the relevant code:

template = Template('''<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>Streaming Example</title>
        {{ js_resources }}
        {{ css_resources }}
    </head>
    <body>
    {{ plot_div }}
    {{ plot_script }}
    </body>
</html>
''')

@app.route("/")
def simple():
    streaming=True
    source = AjaxDataSource(data_url="http://localhost:5000/data", 
                            polling_interval=1000, mode='append')

    fig = figure(title="Streaming Example")
    fig.line( 'x', 'y', source=source)

    js_resources = INLINE.render_js()
    css_resources = INLINE.render_css()

    script, div = components(fig, INLINE)

    html = template.render(
        plot_script=script,
        plot_div=div,
        js_resources=js_resources,
        css_resources=css_resources
    )

    return encode_utf8(html) 

If anyone has any thoughts, I'd be thankful.

Brian

解决方案

First, as a gentle suggestion, please always post complete runnable code examples. It took a few minutes to reproduce all the missing necessary imports, for something that only took seconds to diagnose once there was a runnable script.


Recently some of the BokehJS code paths were made more "strict" which is good in almost every instance, but it appears this left a bad interaction with AjaxDataSource that was not noticed. FWIW when I run example I do see an error in the browser JS console:

Error: attempted to retrieve property array for nonexistent field 'x'

And this is the key to the workround, which is just to make sure the data source does have (empty) columns for x and y:

source.data = dict(x=[], y=[])

There is a complete working script below. I'd ask that you please make an issue on the Bokeh issue tracker with this information so that this bug can be prioritized and fixed


from flask import Flask, jsonify
from jinja2 import Template
import math

from bokeh.plotting import figure
from bokeh.models import AjaxDataSource
from bokeh.embed import components
from bokeh.resources import INLINE
from bokeh.util.string import encode_utf8


app = Flask(__name__)

x, y = 0, 0

@app.route("/data", methods=['POST'])
def get_x():
    global x, y
    x = x + 0.1
    y = math.sin(x)
    return jsonify(x=[x], y=[y])

template = Template('''<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>Streaming Example</title>
        {{ js_resources }}
        {{ css_resources }}
    </head>
    <body>
    {{ plot_div }}
    {{ plot_script }}
    </body>
</html>
''')

@app.route("/")
def simple():
    streaming=True
    source = AjaxDataSource(data_url="http://localhost:5000/data",
                            polling_interval=1000, mode='append')

    source.data = dict(x=[], y=[])

    fig = figure(title="Streaming Example")
    fig.line( 'x', 'y', source=source)

    js_resources = INLINE.render_js()
    css_resources = INLINE.render_css()

    script, div = components(fig, INLINE)

    html = template.render(
        plot_script=script,
        plot_div=div,
        js_resources=js_resources,
        css_resources=css_resources
    )

    return encode_utf8(html)

app.run(debug=True)

这篇关于Flask + Bokeh AjaxDataSource的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆