如何在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)
我期望在快照中是这样的:
我使用的是Bokeh 1.0.4
我们可能需要对文档进行一些改进,因为代码的某些部分没有意义。
push_notebook
是显示真正的Bokeh服务器应用程序(即将modify_doc
传递给show
)的补充。我想不出任何将它们组合在一起的情况。 Bokeh服务器应用程序功能是push_notebook
的严格超集,因此,由于您已经在制作Bokeh服务器应用程序,因此您应该以标准方式更新所有内容。show
(在本例中,在modify_doc
中)这实际上是您获得的异常的直接原因。你应该push_notebook
和Bokeh服务器的整个目的是更新可以有效地发生,而不必每次都创建一个全新的情节。您应该更新现有绘图的数据和属性。这里有一个完整的Bokeh服务器应用程序的工作示例:
https://github.com/bokeh/bokeh/blob/master/examples/howto/server_embed/notebook_embed.ipynb
您应该学习并模仿它,因为它代表了最佳实践。
通过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)
这将是您看到的输出: