Bokeh 独立嵌入内容服务文件夹(v 3.3.0 2023)

问题描述 投票:0回答:1

我正在尝试在远程位置运行服务器来渲染带有圆圈的绘图,以便工具提示包含悬停在其上的项目的图像。

我正在使用 Bokeh 3.3.0 和龙卷风。这是我的代码:

from bokeh.layouts import column
from bokeh.models import ColumnDataSource,HoverTool
from bokeh.plotting import figure
from bokeh.server.server import Server

def bkapp(doc):
    
    #get necessary data...
    dfsource=ColumnDataSource(df)

    hover = HoverTool(tooltips ="""
        <div>
            <div>
                <img
                    src="@_id.png"
                    style="float: left; margin: 0px 5px 5px 0px;"
                    border="2"
                ></img>
            </div>
            <div>
                <span style="font-size: 15px;">@_id</span>
                <span style="font-size: 10px; color: #696;">(@ucx, @ucy)</span>
            </div>
        """)

    # create a plot
    p = figure(sizing_mode="stretch_width", max_width=2000, height=800,
              tools=["pan", 'wheel_zoom',"tap","reset"])
    p.add_tools(hover)

    circle = p.circle(source=dfsource,x="ucx",y="ucy")

    doc.add_root(p)

server = Server({'/': bkapp}, num_procs=4)
server.start()

if __name__ == '__main__':
    print('Opening Bokeh application on http://localhost:5006/')

    server.io_loop.add_callback(server.show, "/")
    server.io_loop.start()

情节按预期工作,但图像无法访问。

文件夹结构很简单:

-cwd
--myapp.py
--imagefolder/

我尝试将 src 设置为:

  • src="imagefolder/@_id.png"
  • src="file://@_id.png"
  • src="http://localhost:5006/@_id.png"

和其他组合,但我认为问题是该文件夹没有被提供服务。有人可以告诉我如何通过 Bokeh API 告诉龙卷风请提供此图像文件夹,以便我可以执行类似 http://localhost:5006/imagefolder/_id.png 的操作并能够看到图像?

python server tooltip bokeh tornado
1个回答
0
投票

所以我基本上最终将散景应用程序嵌入到烧瓶应用程序中,这一点也不优雅,并且说明如果在散景中混合服务器编程和可视化是一个糟糕的主意。但无论如何,这就是这个想法:

from threading import Thread

from flask import Flask, render_template,request, send_from_directory
from tornado.ioloop import IOLoop

from bokeh.embed import server_document

#from bokeh. more bokeh imports...

app = Flask(__name__, static_url_path='')


def display_event():
    """
    Function to build a suitable CustomJS to display the current event
    in the div model.
    """
    return CustomJS(args={}, code=f"""
        #more custom js
    """
    )



def bkapp(doc):
    
    
    print(os.getcwd())
    dfsource=ColumnDataSource(datacontainer.df)
    dfsignssource=ColumnDataSource(datacontainer.dfsigns)
    doc.theme = "dark_minimal"

    hover = HoverTool(tooltips ="""
        <div>
            <div>
                <img
                    src="http://localhost:8000/img/@_id.png" width="500" 
                    style="float: left; margin: 0px 5px 5px 0px;"
                    border="2"
                ></img>
            </div>
            <div>
                <span style="font-size: 15px;">@_id</span>
                <span style="font-size: 10px; color: #696;">(@ucx, @ucy)</span>
            </div>
        """)

    # create a plot
    p = figure(sizing_mode="stretch_width", max_width=2000, height=800,
              tools=["pan","box_select", "wheel_zoom","tap","reset"])
    p.add_tools(hover)

    circle = p.circle(source=dfsource,x="ucx",y="ucy",
                          fill_color="color", 
                          size=7,line_width=0.3,line_color="white",name="circles")

    
    p.js_on_event(events.SelectionGeometry, display_event())

    # show the results
    doc.add_root(p)

#bokeh app
@app.route('/', methods=['GET'])
def bkapp_page():
    script = server_document('http://localhost:5006/bkapp')
    return render_template("embed.html", script=script, template="Flask")

#serving images with flask to be consumed by bokeh
@app.route('/img/<path:path>')
def send_js(path):
    return send_from_directory('images', path)

def bk_worker():
    # Can't pass num_procs > 1 in this configuration. If you need to run multiple
    # processes, see e.g. flask_gunicorn_embed.py
    server = Server({'/bkapp': bkapp}, io_loop=IOLoop(), allow_websocket_origin=["localhost:8000"])
    server.start()
    server.io_loop.start()

Thread(target=bk_worker).start()

if __name__ == '__main__':
    print('Opening single process Flask app with embedded Bokeh application on http://localhost:8000/')
    print()
    print('Multiple connections may block the Bokeh app in this configuration!')
    print('See "flask_gunicorn_embed.py" for one way to run multi-process')
    app.run(port=8000)
    

这里有更多信息 github.com/realpython/flask-bokeh-example 和这里 bokeh 用户指南

© www.soinside.com 2019 - 2024. All rights reserved.