将带有小部件的交互式散景图导出到独立的 HTML

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

我正在寻找一种方法将包含带有小部件的交互式散景图的 Jupyter Notebook 导出到独立的 HTML。当使用工具栏中的 Jupyter NB“下载到”HTML 功能时,除了交互式 Bokeh 图之外的所有内容都可以很好地导出,静态 Bokeh 图也是如此(静态图也是“交互式”的,但基础数据不会改变)

如何使用在独立 HTML 中工作的小部件获得交互式绘图?

您可以在下面找到安装了 Bokeh 13.0 的 Jupyter Notebook 的工作示例。

import numpy as np
import pandas as pd

from bokeh.io import save, curdoc,output_file ,show, output_notebook, push_notebook
from bokeh.plotting import figure, gridplot

from bokeh.models import ColumnDataSource, Panel
from bokeh.models.widgets import Slider, Tabs, DataTable, TableColumn
from bokeh.layouts import layout, WidgetBox
from bokeh.application.handlers import FunctionHandler
from bokeh.application import Application
# output_file('tryout.html')
output_notebook()

# Static Bokeh plot:
data = pd.DataFrame(np.random.random([10,2]),columns=['x','y'])
dataMean = pd.DataFrame([],columns=['mean','std'])

dataMean.loc[:,'mean'] =data.mean()
dataMean.loc[:,'std'] =data.std()        
src1 = ColumnDataSource(data)
src2 = ColumnDataSource(dataMean)

p = figure(plot_width = 700, plot_height = 400, 
title = 'Test case',x_axis_label = 'x', y_axis_label = 'y')

p.line(source=src1,y='y',x='x',color='blue',line_width=2)
p.circle(source=src1,y='y',x='x',color='green')

columnsT = [TableColumn(field="mean", title="mean"),
        TableColumn(field="std", title='std')]
data_table = DataTable(source=src2, columns=columnsT, width=400, height=400)    
data_table.index_position = None
controls = WidgetBox(data_table)    
layO = layout([[p],[controls]])
# Make a tab with the layout 
tab1 = Panel(child=layO, title = 'test')
tabs = Tabs(tabs=[tab1])
show(tabs)

# Now the same plot, but fitted with a slider widget
def modify_doc(doc):

    def make_dataset(N = 2):

        data = pd.DataFrame(np.random.random([N,2]),columns=['x','y'])
        dataMean = pd.DataFrame([],columns=['mean','std'])

        dataMean.loc[:,'mean'] =data.mean()
        dataMean.loc[:,'std'] =data.std()        
        return ColumnDataSource(data),ColumnDataSource(dataMean)

    def make_plot(src):
        # Blank plot with correct labels
        p = figure(plot_width = 700, plot_height = 400, 
                  title = 'Test case',x_axis_label = 'x', y_axis_label = 'y')

        p.line(source=src,y='y',x='x',color='blue',line_width=2)
        p.circle(source=src,y='y',x='x',color='green')
        return p
    def update(attr, old, new):
        new_src, new_src2 = make_dataset(N_select.value)

        src.data.update(new_src.data)
        src2.data.update(new_src2.data)

    N_select = Slider(start = 2, end = 20, step = 1, value = 2, title = 'number of points',width=700)
    N_select.on_change('value', update)    

    columnsT = [
        TableColumn(field="mean", title="mean"),
        TableColumn(field="std", title='std')]

    src, src2 = make_dataset(N_select.value)
    data_table = DataTable(source=src2, columns=columnsT, width=400, height=400)    
    data_table.index_position = None

    p = make_plot(src)
    # Put controls in a single element
    controls = WidgetBox(N_select,data_table)
    layO = layout([[p],[controls]])
    # Make a tab with the layout 
    tab1 = Panel(child=layO, title = 'test')  
    tabs = Tabs(tabs=[tab1])    
    doc.add_root(tabs)
handler= FunctionHandler(modify_doc)
app = Application(handler)
show(app)

如果我将output_notebook()更改为output_file('tryout.html'),它会给我以下错误,我不明白,也可以找到解决方案:

运行时错误:没有为笔记本类型安装显示挂钩无

希望有人能够帮助我解决这个问题。

提前致谢!

html export jupyter-notebook bokeh
1个回答
5
投票

编辑:早期的答案通常仍然是正确的,但是最近出现了一些发展,例如PyScript,可以在静态 HTML 页面的浏览器中提供“运行 Python 代码”(包括 Bokeh 服务器应用程序代码)的选项。 Holoviz/Panel 团队处于这方面的最前沿


你所要求的是不可能的,至少在我理解你的问题时是不可能的。您已经创建了一个 Bokeh 服务器应用程序,带有真正的 Python 代码回调。独立的 HTML 文档不可能运行真正的 Python 代码,因为浏览器根本没有能力运行 Python 代码。真正的 Python 代码回调需要实时运行的 Python 解释器进程。当您在笔记本中嵌入散景服务器应用程序时,正如您上面所做的那样,该进程就是 IPython 内核。

如果您只是想要一个可以在笔记本外部运行的 Bokeh 服务器应用程序(需要在 Bokeh 服务器上运行,因为这是运行回调的 Python 进程),最简单的方法是将所有代码放入您需要的脚本中。运行

bokeh serve --show myapp.py

此类应用程序的大致轮廓是:

from bokeh.io import curdoc
from bokeh.layouts import column
from bokeh.models import Slider
from bokeh.plotting import figure

# create plots
plot = figure(...)

# create widgets
slider = Slider(...)

# add callbacks to widgets
def update(attr, old, new):
    pass
slider.on_change('value', update)

# put things in a layout
layout = column(slider, plot)

# add to curdoc
curdoc().add_root(layout)

或者,也可以将 Bokeh 服务器应用程序嵌入“常规”Python 脚本中。为此,请参阅将 Bokeh 服务器嵌入为库

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