散景仪表板布局;小部件布局不显示

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 启动散景服务器 关于错误,提到