散景仪表板布局;小部件布局不显示
Bokeh dashboard layout; widget layout does not show
我正在尝试创建一个 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
我是否需要在现有代码中添加任何其他内容来解决此问题并部署小部件和绘图?
这是 pandas_bokeh 的已知问题。如果您有相同的地块名称,则会出现此错误,但在您使用 curdoc/server 类型显示时会出现此错误。
import curdoc
而不是 show(bokehlayout)
,使用 curdoc().add_root(bokeh_layout)
并使用 bokeh serve --show filename.py
启动散景服务器
关于错误,提到
我正在尝试创建一个 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
我是否需要在现有代码中添加任何其他内容来解决此问题并部署小部件和绘图?
这是 pandas_bokeh 的已知问题。如果您有相同的地块名称,则会出现此错误,但在您使用 curdoc/server 类型显示时会出现此错误。
import curdoc
而不是 show(bokehlayout)
,使用 curdoc().add_root(bokeh_layout)
并使用 bokeh serve --show filename.py
启动散景服务器
关于错误,提到