散景仪表板布局;小部件布局不显示
Posted
技术标签:
【中文标题】散景仪表板布局;小部件布局不显示【英文标题】:Bokeh dashboard layout; widget layout does not show 【发布时间】:2021-11-16 05:16:32 【问题描述】:我正在尝试创建 Bokeh 仪表板,但在尝试部署它时遇到了问题。本质上,当仪表板启动时,绘图将显示,但用于交互式更新绘图的小部件不会。这是我的代码:-
import numpy as np
import pandas as pd
import pandas_bokeh
from bokeh.io import show
from bokeh.layouts import column, layout, row
from bokeh.models import DateRangeSlider, Dropdown
#color palette
colors=['#FDE724','#D01C8B','#4DAC26']
#define the categorical variable
category_a = ['A','B','C']
category_b = ['X','Y','Z']
#set random seed to make the dataset reproducible
np.random.seed(42)
#create a dataset
#df_random = pd.DataFrame(
# 'id': np.arange(0, 15),
# 'month':np.random.randint(1, 12, 15),
# 'sensor_1': np.random.uniform(0, 1,15),
# 'sensor_2': np.random.uniform(10, 15, 15),
# 'sensor_3': np.random.randint(0, 20, 15),
# 'category': np.random.choice(category, 15, p=[0.2, 0.4, 0.4]),
#)
df_random2 = pd.DataFrame(
'id': np.arange(0, 30),
'date': pd.date_range(start='1/1/2021', periods=30, freq='D'),
'month':np.random.randint(1, 12, 30),
'sensor_1': np.random.uniform(0, 1,30),
'sensor_2': np.random.uniform(10, 15, 30),
'sensor_3': np.random.randint(0, 20, 30),
'categorya': np.random.choice(category_a, 30, p=[0.2, 0.4, 0.4]),
'categoryb': np.random.choice(category_b, 30, p=[0.6, 0.2, 0.2]),
)
#set index to id column
df_random2=df_random2.set_index('id')
df_random2.shape
df_random2.head()
mindate=df_random2['date'].min()
maxdate=df_random2['date'].max()
menucols = [("Category A", "categorya"),("Category B","categoryb")]
date_range_slider = DateRangeSlider(value=(mindate, maxdate),
start=mindate, end=maxdate)
category_picker = Dropdown(label = "Column select", button_type="default", menu=menucols)
# Plot1 - Line plot
p_line= df_random2.groupby(['date']).mean().plot_bokeh(kind="line",y="sensor_2",color='#d01c8b',plot_data_points=True,show_figure=False)
# Plot2- Barplot
p_bar = df_random2.groupby(['date']).mean().plot_bokeh(kind="bar",y='sensor_2', colormap=colors,show_figure=False)
# Plot3- stacked bar chart
df_sensor=df_random2.drop(['date','month','categorya'],axis=1)
p_stack=df_sensor.groupby(['categoryb']).mean().plot_bokeh(kind='barh', stacked=True,colormap=colors,show_figure=False)
#Plot4- Scatterplot
p_scatter = df_random2.plot_bokeh(kind="scatter", x="month", y="sensor_2",category="categoryb",colormap=colors,show_figure=False)
#Plot5- Pie chart
p_pie= df_random2.groupby(['categoryb']).mean().plot_bokeh.pie(y='sensor_1',colormap=colors,show_figure=False)
#Plot6- Histogram
p_hist=df_sensor.plot_bokeh(kind='hist', histogram_type="stacked",bins=6,colormap=colors, show_figure=False)
widgets = [date_range_slider,category_picker]
#Make Dashboard with Grid Layout:
plots=pandas_bokeh.plot_grid([[p_line, p_bar,p_stack],[p_scatter, p_pie,p_hist]], plot_width=400)
bokehlayout = layout(widgets,plots)
show(bokehlayout)
这是我收到的错误消息:-
RuntimeError: Models must be owned by only a single document, HoverTool(id='2836', ...) is already in a doc
---------------------------------------------------------------------------
RuntimeError Traceback (most recent call last)
m:\bokehdash\exploratorydatanalysis.py in <module>
83 bokehlayout = layout(widgets,plots)
84
---> 85 show(bokehlayout)
~\anaconda3\lib\site-packages\bokeh\io\showing.py in show(obj, browser, new, notebook_handle, notebook_url, **kw)
137 return run_notebook_hook(state.notebook_type, 'app', obj, state, notebook_url, **kw)
138
--> 139 return _show_with_state(obj, state, browser, new, notebook_handle=notebook_handle)
140
141 #-----------------------------------------------------------------------------
~\anaconda3\lib\site-packages\bokeh\io\showing.py in _show_with_state(obj, state, browser, new, notebook_handle)
175
176 if state.file or not shown:
--> 177 _show_file_with_state(obj, state, new, controller)
178
179 return comms_handle
~\anaconda3\lib\site-packages\bokeh\io\showing.py in _show_file_with_state(obj, state, new, controller)
158
159 '''
--> 160 filename = save(obj, state=state)
161 controller.open("file://" + filename, new=NEW_PARAM[new])
162
~\anaconda3\lib\site-packages\bokeh\io\saving.py in save(obj, filename, resources, title, template, state, **kwargs)
84
85 filename, resources, title = _get_save_args(state, filename, resources, title)
---> 86 _save_helper(obj, filename, resources, title, template, theme)
87 return abspath(filename)
88
~\anaconda3\lib\site-packages\bokeh\io\saving.py in _save_helper(obj, filename, resources, title, template, theme)
146 '''
147 from ..embed import file_html
--> 148 html = file_html(obj, resources, title=title, template=template, theme=theme)
149
150 with open(filename, mode="w", encoding="utf-8") as f:
~\anaconda3\lib\site-packages\bokeh\embed\standalone.py in file_html(models, resources, title, template, template_variables, theme, suppress_callback_warning, _always_new)
301 models_seq = models
302
--> 303 with OutputDocumentFor(models_seq, apply_theme=theme, always_new=_always_new) as doc:
304 (docs_json, render_items) = standalone_docs_json_and_render_items(models_seq, suppress_callback_warning=suppress_callback_warning)
305 title = _title_from_models(models_seq, title)
~\anaconda3\lib\contextlib.py in __enter__(self)
111 del self.args, self.kwds, self.func
112 try:
--> 113 return next(self.gen)
114 except StopIteration:
115 raise RuntimeError("generator didn't yield") from None
~\anaconda3\lib\site-packages\bokeh\embed\util.py in OutputDocumentFor(objs, apply_theme, always_new)
132 doc = Document()
133 for model in objs:
--> 134 doc.add_root(model)
135
136 # handle a single shared document
~\anaconda3\lib\site-packages\bokeh\document\document.py in add_root(self, model, setter)
319 self._roots.append(model)
320 finally:
--> 321 self._pop_all_models_freeze()
322 self._trigger_on_change(RootAddedEvent(self, model, setter))
323
~\anaconda3\lib\site-packages\bokeh\document\document.py in _pop_all_models_freeze(self)
1102 self._all_models_freeze_count -= 1
1103 if self._all_models_freeze_count == 0:
-> 1104 self._recompute_all_models()
1105
1106 def _recompute_all_models(self):
~\anaconda3\lib\site-packages\bokeh\document\document.py in _recompute_all_models(self)
1125 d._detach_document()
1126 for a in to_attach:
-> 1127 a._attach_document(self)
1128 self._all_models = recomputed
1129 self._all_models_by_name = recomputed_by_name
~\anaconda3\lib\site-packages\bokeh\model.py in _attach_document(self, doc)
690 '''
691 if self._document is not None and self._document is not doc:
--> 692 raise RuntimeError("Models must be owned by only a single document, %r is already in a doc" % (self))
693 doc.theme.apply_to_model(self)
694 self._document = doc
RuntimeError: Models must be owned by only a single document, HoverTool(id='2836', ...) is already in a doc
我是否需要在现有代码中添加任何其他内容来解决此问题并同时部署小部件和绘图?
【问题讨论】:
【参考方案1】:这是 pandas_bokeh 的已知问题。如果您具有相同的绘图名称,则会出现此错误,但是当您使用 curdoc/server 类型显示时它会起作用。
import curdoc
而不是show(bokehlayout)
,使用curdoc().add_root(bokeh_layout)
并使用bokeh serve --show filename.py
启动散景服务器
关于错误,提到了here
【讨论】:
感谢您的建议。我已修改我的代码以使用import curdoc
等。但是当我在 powershell 中启动应用程序时,只会打开一个空白浏览器窗口。这可能是什么原因造成的?
使用 curdoc 对我来说一切都很好。小部件和绘图
抱歉,你说得对,它确实有效。在我的最后做了一个轻微的错字。谢谢你:)以上是关于散景仪表板布局;小部件布局不显示的主要内容,如果未能解决你的问题,请参考以下文章