通过Select Widget引发Jupyter Notebook的交互式选择“模型必须仅由一个文档拥有”错误

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

如何在Jupyter Notebook上通过a selection widget创建一个带有散景的交互式条形图?

为什么Notebook会引发以下错误:

“RuntimeError:模型必须只由一个文档拥有,Title(id ='1044',...)已经在doc ERROR中:tornado.access:500 GET /autoload.js?bokeh-autoload-element=1002&bokeh -absolute-url = http://localhost:54277&resources=none(:1)117.01ms“

我从github仔细阅读了这个例子和Google Bokeh Group的类似情况,后者他们运行的是散景服务器而不是jupyter内核

output_notebook()

dct={'Date' : ["2018-01-07", "2018-01-12", "2018-01-13", "2018-01-14", "2018-01-20", "2018-01-24"],'Activity' : ['A','B','A','B','A','B'],'Count' : [1, 2, 5, 3, 7, 1]}
df=pd.DataFrame(dct)

activity_list=df['Activity'].unique().tolist().copy()
activity_selected='A'
def modify_doc(doc):
     def make_plot(cdf):
         plot = figure()
         plot.vbar(x=cdf.Date, top=cdf.Count, width=0.9)
         push_notebook()
         show(plot, notebook_handle = True)
         return plot
     def update_plot(attr, old, new):
         activity =  select.value
         sdf = df.copy()
         sdf = sdf[sdf['Activity'] == activity]
         layout.children[0] = make_plot(sdf)


     select = Select(title='Select Activity', value=activity_selected, options=activity_list)
     select.on_change('value', update_plot)
     p=make_plot(df)
     layout=column(select, p)
     doc.add_root(layout)
show(modify_doc)

我期望在快照中是这样的:

enter image description here

我使用的是Bokeh 1.0.4

python widget bokeh
2个回答
1
投票

我们可能需要对文档进行一些改进,因为代码的某些部分没有意义。

  • push_notebook是显示真正的Bokeh服务器应用程序(即将modify_doc传递给show)的补充。我想不出任何将它们组合在一起的情况。 Bokeh服务器应用程序功能是push_notebook的严格超集,因此,由于您已经在制作Bokeh服务器应用程序,因此您应该以标准方式更新所有内容。
  • 永远不应该在Bokeh服务器应用程序代码中调用show(在本例中,在modify_doc中)这实际上是您获得的异常的直接原因。你应该
  • 你不应该每次都制作一个新的情节! push_notebook和Bokeh服务器的整个目的是更新可以有效地发生,而不必每次都创建一个全新的情节。您应该更新现有绘图的数据和属性。

这里有一个完整的Bokeh服务器应用程序的工作示例:

https://github.com/bokeh/bokeh/blob/master/examples/howto/server_embed/notebook_embed.ipynb

您应该学习并模仿它,因为它代表了最佳实践。


0
投票

通过Select小部件选择绘图的正确代码是:

activity_list=df['Activity'].unique().tolist().copy()
df['Date']=pd.to_datetime(df['Date'])

activity_selected='A'

def modify_doc(doc):

    df_r=df.copy()
    source = ColumnDataSource(data=df_r)
    plot=figure(title='Daily Hours',x_axis_type="datetime")
    plot.vbar(x="Date", top="Count",source=source, width=4)
    def update_plot(attr, old, new):
        activity =  select.value
        data = df_r[df_r['Activity'] == activity]
        source.data = ColumnDataSource(data=data).data

    select = Select(title='Select Activity', value=activity_selected, options=activity_list)
    select.on_change('value', update_plot)

    layout=column(select, plot)
    doc.add_root(layout)
show(modify_doc)

这将是您看到的输出:

enter image description here enter image description here

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