How to embed a bokeh server in a standalone

前提是你 提交于 2019-12-13 17:56:15

问题


I'm trying to embed a bokeh server in a standalone document as presented here. I'm quite lost and couldn't wrap my head around the example provided. I tried to implement it in the following example, but when I run it doesn't show the application. Could someone show me how to create this standalone?

Thanks

from bokeh.io import show, curdoc
from bokeh.models import  ColumnDataSource, Legend, CustomJS, Select
from bokeh.plotting import figure
from bokeh.palettes import Category10
from bokeh.layouts import row
import pandas as pd
from bokeh.server.server import Server

def test(doc):
    df0 = pd.DataFrame({'x': [1, 2, 3], 'Ay' : [1, 5, 3], 'A': [0.2, 0.1, 0.2], 'By' : [2, 4, 3], 'B':[0.1, 0.3, 0.2]})

    columns = ['A', 'B']

    tools_to_show = 'box_zoom,save,hover,reset'
    p = figure(plot_height =300, plot_width = 1200, 
               toolbar_location='above',
               tools=tools_to_show)

    legend_it = []
    color = Category10[10]
    columns = ['A', 'B']
    source = ColumnDataSource(df0)
    c = []
    for i, col in enumerate(columns):
        c.append(p.line('x', col, source=source, name=col, color=color[i]))
        legend_it.append((col, [c[i]]))


    legend = Legend(items=legend_it, location=(5,114))#(0, -60))

    p.add_layout(legend, 'right')

    select = Select(title="color", value=color[0],
                    options = color)
    callbacks = CustomJS(args=dict(renderer=c[0], select=select), code ="""
        renderer.glyph.line_color = select.value;
        renderer.trigger('change')
    """)

    select.callback = callbacks

    layout = row(select, p)

    curdoc().add_root(layout)

server = Server(test)
server.start()

Based on the accepted answer I adapted the code and it works:

from bokeh.models import  ColumnDataSource, Legend, CustomJS, Select
from bokeh.plotting import figure
from bokeh.palettes import Category10
from bokeh.layouts import row
import pandas as pd
from bokeh.server.server import Server


def test(doc):
    df0 = pd.DataFrame({'x': [1, 2, 3], 'Ay' : [1, 5, 3], 'A': [0.2, 0.1, 0.2], 'By' : [2, 4, 3], 'B':[0.1, 0.3, 0.2]})

    columns = ['A', 'B']

    tools_to_show = 'box_zoom,save,hover,reset'
    p = figure(plot_height =300, plot_width = 1200, 
               toolbar_location='above',
               tools=tools_to_show)

    legend_it = []
    color = Category10[10]
    columns = ['A', 'B']
    source = ColumnDataSource(df0)
    c = []
    for i, col in enumerate(columns):
        c.append(p.line('x', col, source=source, name=col, color=color[i]))
        legend_it.append((col, [c[i]]))


    legend = Legend(items=legend_it, location=(5,114))#(0, -60))

    p.add_layout(legend, 'right')

    select = Select(title="color", value=color[0],
                    options = color)
    callbacks = CustomJS(args=dict(renderer=c[0], select=select), code ="""
        renderer.glyph.line_color = select.value;
        renderer.trigger('change')
    """)

    select.callback = callbacks

    layout = row(select, p)

    doc.add_root(layout)


server = Server({'/': test}, num_procs=1)
server.start()

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

回答1:


There is a full working example for programmatically running a bokeh server without using "bokeh serve ..." on the bokeh github site:

https://github.com/bokeh/bokeh/blob/master/examples/howto/server_embed/standalone_embed.py

from bokeh.layouts import column
from bokeh.models import ColumnDataSource, Slider
from bokeh.plotting import figure
from bokeh.server.server import Server
from bokeh.themes import Theme

from bokeh.sampledata.sea_surface_temperature import sea_surface_temperature

def modify_doc(doc):
    df = sea_surface_temperature.copy()
    source = ColumnDataSource(data=df)

    plot = figure(x_axis_type='datetime', y_range=(0, 25), y_axis_label='Temperature (Celsius)',
                  title="Sea Surface Temperature at 43.18, -70.43")
    plot.line('time', 'temperature', source=source)

    def callback(attr, old, new):
        if new == 0:
            data = df
        else:
            data = df.rolling('{0}D'.format(new)).mean()
        source.data = ColumnDataSource(data=data).data

    slider = Slider(start=0, end=30, value=0, step=1, title="Smoothing by N Days")
    slider.on_change('value', callback)

    doc.add_root(column(slider, plot))

    doc.theme = Theme(filename="theme.yaml")

# Setting num_procs here means we can't touch the IOLoop before now, we must
# let Server handle that. If you need to explicitly handle IOLoops then you
# will need to use the lower level BaseServer class.
server = Server({'/': modify_doc}, 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()

If we take this a template and integrate your code, it looks like this:

from bokeh.models import  ColumnDataSource, Legend, CustomJS, Select
from bokeh.plotting import figure
from bokeh.palettes import Category10
from bokeh.layouts import row
import pandas as pd
from bokeh.server.server import Server

from bokeh.sampledata.sea_surface_temperature import sea_surface_temperature

def test(doc):
    df0 = pd.DataFrame({'x': [1, 2, 3], 'Ay' : [1, 5, 3], 'A': [0.2, 0.1, 0.2], 'By' : [2, 4, 3], 'B':[0.1, 0.3, 0.2]})

    columns = ['A', 'B']

    tools_to_show = 'box_zoom,save,hover,reset'
    p = figure(plot_height =300, plot_width = 1200, 
               toolbar_location='above',
               tools=tools_to_show)

    legend_it = []
    color = Category10[10]
    columns = ['A', 'B']
    source = ColumnDataSource(df0)
    c = []
    for i, col in enumerate(columns):
        c.append(p.line('x', col, source=source, name=col, color=color[i]))
        legend_it.append((col, [c[i]]))


    legend = Legend(items=legend_it, location=(5,114))#(0, -60))

    p.add_layout(legend, 'right')

    select = Select(title="color", value=color[0],
                    options = color)
    callbacks = CustomJS(args=dict(renderer=c[0], select=select), code ="""
        renderer.glyph.line_color = select.value;
        renderer.trigger('change')
    """)

    select.callback = callbacks

    layout = row(select, p)

    doc.add_root(layout)


server = Server({'/': test}, num_procs=1)
server.start()

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

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


来源:https://stackoverflow.com/questions/51802159/how-to-embed-a-bokeh-server-in-a-standalone

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!