【问题标题】:Bokeh: Models must be owned by only a single document散景:模型必须由单个文档拥有
【发布时间】:2017-02-05 17:42:09
【问题描述】:

我在 Jupyter 笔记本中使用 Bokeh 0.12.2,它经常抛出有关“模型必须仅由单个文档拥有”的异常:

---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
<ipython-input-23-f50ac7abda5e> in <module>()
      2     ea.legend.label_text_font_size = '10pt'
      3 
----> 4 show(column([co2, co, nox, o3]))

C:\Users\pokeeffe\AppData\Local\Continuum\Anaconda3\lib\site-packages\bokeh\io.py in show(obj, browser, new, notebook_handle)
    308     '''
    309     if obj not in _state.document.roots:
--> 310         _state.document.add_root(obj)
    311     return _show_with_state(obj, _state, browser, new, notebook_handle=notebook_handle)
    312 

C:\Users\pokeeffe\AppData\Local\Continuum\Anaconda3\lib\site-packages\bokeh\document.py in add_root(self, model)
    443             self._roots.append(model)
    444         finally:
--> 445             self._pop_all_models_freeze()
    446         self._trigger_on_change(RootAddedEvent(self, model))
    447 

C:\Users\pokeeffe\AppData\Local\Continuum\Anaconda3\lib\site-packages\bokeh\document.py in _pop_all_models_freeze(self)
    343         self._all_models_freeze_count -= 1
    344         if self._all_models_freeze_count == 0:
--> 345             self._recompute_all_models()
    346 
    347     def _invalidate_all_models(self):

C:\Users\pokeeffe\AppData\Local\Continuum\Anaconda3\lib\site-packages\bokeh\document.py in _recompute_all_models(self)
    367             d._detach_document()
    368         for a in to_attach:
--> 369             a._attach_document(self)
    370         self._all_models = recomputed
    371         self._all_models_by_name = recomputed_by_name

C:\Users\pokeeffe\AppData\Local\Continuum\Anaconda3\lib\site-packages\bokeh\model.py in _attach_document(self, doc)
     89         '''This should only be called by the Document implementation to set the document field'''
     90         if self._document is not None and self._document is not doc:
---> 91             raise RuntimeError("Models must be owned by only a single document, %r is already in a doc" % (self))
     92         doc.theme.apply_to_model(self)
     93         self._document = doc

RuntimeError: Models must be owned by only a single document, <bokeh.models.tickers.DaysTicker object at 0x00000000042540B8> is already in a doc

触发器总是调用show(...)(虽然从来没有在内核启动后第一次调用,只有后续调用)。

根据文档,我认为reset_output() 会使我的笔记本恢复到可操作状态,但异常仍然存在。通过反复试验,我确定有必要重新定义传递给show() 的所有内容。这使得交互式工作变得繁琐且容易出错。

[Ref]:

reset_output(state=None)

  清除所有输出模式的默认状态。

  返回:


  • 我对 reset_output() 的看法是否正确——它应该解决导致此异常的情况吗?

  • 否则,我该如何避免这种异常?

【问题讨论】:

  • 我的第一个建议是升级。 Bokeh 和 Notebook 都是非常大的、跨运行时的东西,集成它们是不断改进的挑战。我知道自0.12.2 以来一直有工作,尽管我没有时间研究细节。否则,请发布完整的代码示例以检查/试用。例如,我知道多次显示相同的图可以正常工作(我只是尝试确定),因此如果没有测试笔记本来重现问题,就无法推测您的具体问题是什么。

标签: bokeh


【解决方案1】:
column_data_source = ColumnDataSource(dataframe)

在 jupyter notebook 中使用列数据源的每一行之后,我们必须简单地重新创建它。列数据源好像不能在同一个代码中多次使用。

这似乎有点小技巧,但当我遇到同样的错误时它对我有用。

【讨论】:

    【解决方案2】:

    我一直在使用 jupyterlab notebook 迭代使用散景、全息视图和面板对大量数据进行可视化,并且定期遇到此问题。

    这里还有一些可能会有所帮助的其他事项。请注意,p 用作该图的散景常规名称。我在这个旧线程上发帖是因为它是我在 Google 搜索错误消息时的最高结果。

    尝试清除文档(位于docs):

    from bokeh.io import curdoc
    
    curdoc().clear()
    

    我观察到panel 能够显示散景对象,即使散景显示无法显示。

    import panel as pn
    
    pn.extension()
    
    pn.pane.Bokeh(p)
    

    深入研究即使没有散景,面板如何显示对象,我注意到function,它为我解决了这个问题:

    import panel as pn
    
    pn.io.model.remove_root(p)
    

    如果您没有安装面板,这里是上面的来源code

    from bokeh.models import Model
    
    for model in p.select({'type': Model}):
        prev_doc = model.document
        model._document = None
        if prev_doc:
            prev_doc.remove_root(model)
    

    希望这对某人或未来的我有所帮助。

    【讨论】:

      【解决方案3】:

      在创建每个情节后尝试使用。 add_root 会将该模型添加为当前文档的根目录,确保将每个模型添加到单个文档中:

          curdoc().add_root(column([plot]))
          curdoc().title = doc_title //Add a title to the doc
          show(figure)
      

      注意:column(the list of plots) 可以替换为任何继承 Model 类的对象。

      有关add_root 和散景文档的更多详细信息,请参阅链接:https://docs.bokeh.org/en/latest/docs/reference/document.html?highlight=add_root#bokeh.document.document.Document.add_root

      【讨论】:

      • 欢迎来到 StackOverFlow,您能否添加更多详细信息,说明您的答案如何达到问题要求以及与其他提议的问题相比如何?
      【解决方案4】:

      此解决方案无需升级或降级软件包即可工作。

      try:
          reset_output()
          output_notebook()
          show(p)
      except:
          output_notebook()
          show(p)
      

      这里提供的解决方案:

      https://github.com/bokeh/bokeh/issues/8579

      【讨论】:

        【解决方案5】:

        似乎可以通过区分源名称来修复 像这样:

        source1 = df
        p1.circle('A', 'B', source=source1)
        
        source2 = df
        p2 = figure()
        p2.circle('C', 'D', source=source2)
        
        sourceN = df
        p2 = figure()
        p2.circle('X', 'Y', source=sourceN)
        

        【讨论】:

          【解决方案6】:

          在我升级到 bokeh 版本 1.01 后,我在使用来自 bokeh.embed 的 file_html 时遇到了此错误消息。再次降级到散景版本 0.12.16 解决了它。 (点安装散景==0.12.16) 请注意确定原因。

          【讨论】:

          • 从 1.0.1 到 0.13.0 为我修复了它。
          【解决方案7】:

          这可能是因为具有相同名称的对象冲突。您每次都需要创建全新的对象。

          【讨论】:

            猜你喜欢
            • 2021-09-14
            • 2021-12-18
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-03-01
            • 2017-01-14
            • 1970-01-01
            • 2019-04-17
            相关资源
            最近更新 更多