【问题标题】:Bokeh RuntimeError: Models must be owned by only a single document, Selection(id='1057', ...) is already in a docBokeh RuntimeError: 模型必须只属于一个文档,Selection(id='1057', ...) 已经在一个文档中
【发布时间】:2020-03-01 19:33:42
【问题描述】:

我正在尝试在 Bokeh 中绘制多个图形,但出现以下错误:

RuntimeError: Models must be owned by only a single document, Selection(id='1057', ...) is already in a doc.

我知道这是在尝试在多个文档中使用相同的对象时造成的,但我不明白我在哪里这样做。这是整个(简化的)代码。

我正在使用 Bokeh 1.4.0。

from bokeh.plotting import figure, show
from bokeh.layouts import row, gridplot
from bokeh.models import ColumnDataSource
from bokeh.io import output_file
import pandas as pd

feature_groups  = [['ciao'],['bye']]


df = pd.DataFrame.from_dict({'x':[0,1,2,3,4], 'y':[2,3,4,5,6]})
x_test = [0,1,2,3,4]
y_test = [2,3,4,5,6]
source = ColumnDataSource(df)


for features_columns in feature_groups:
    output_file('features_labels' + features_columns[0] +'.html')
    p = []

    for k,f in enumerate(features_columns):
        p_k = figure(title=f)
        p_k.circle(x=f, y='ki', line_width=2, source=source,fill_alpha=0.5,line_alpha=0.5)
        p_k.circle_cross( x=x_test, y=y_test, color='red',fill_alpha=0.5,line_alpha=0.5)
        p_k.circle_cross( x = x_test, y = y_test, color='green',fill_alpha=0.5,line_alpha=0.5)
        p_k.xaxis.axis_label = f
        p_k.yaxis.axis_label = 'ki'
        p.append(p_k)
    grid = gridplot(p, ncols=2)
    show(grid)

提前谢谢你

【问题讨论】:

  • 我刚刚发布了一个类似问题的答案here,这可能会有所帮助。

标签: bokeh


【解决方案1】:

使用这个函数 show_bokeh(grid)

def show_bokeh(plot_fig):
    try:
        bpl.reset_output()
        bpl.output_notebook()
        bpl.show(plot_fig)
    except:
        bpl.output_notebook()
        bpl.show(plot_fig) 

而不是 show()

【讨论】:

    【解决方案2】:

    1) 就像错误所说的每个散景模型(在这种情况下为 ColumnDataSource 的实例)只能添加到散景 Document 一次,所以只需将 source = ColumnDataSource(df) 移动到 for 循环。

    编辑(感谢bigreddot):显然您只能在同一散景Document 中的字形和绘图之间共享相同的source,而不能在不同文档之间共享。 output_filesaveshow 等方法会隐式创建新的散景 Document,因此在原始代码中使用相同的 source 和两个 output_file 语句总是会导致问题

    2) 您引用了 ColumnDataSource 中不存在的字段,例如“ki”等。我将它们替换为 x='x'y='y'

    请参阅以下更正且有效的代码:

    from bokeh.plotting import figure, show
    from bokeh.layouts import row, gridplot
    from bokeh.models import ColumnDataSource
    from bokeh.io import output_file
    import pandas as pd
    
    feature_groups  = [['ciao'],['bye']]
    
    df = pd.DataFrame.from_dict({'x':[0,1,2,3,4], 'y':[2,3,4,5,6]})
    x_test = [0,1,2,3,4]
    y_test = [2,3,4,5,6]
    
    for features_columns in feature_groups:
        output_file('features_labels' + features_columns[0] +'.html')
        p = []
        source = ColumnDataSource(df)
    
        for k,f in enumerate(features_columns):
            p_k = figure(title=f)
            p_k.circle(x='x', y='y', line_width=2, source=source,fill_alpha=0.5,line_alpha=0.5)
            p_k.circle_cross( x=x_test, y=y_test, color='red',fill_alpha=0.5,line_alpha=0.5)
            p_k.circle_cross( x = x_test, y = y_test, color='green',fill_alpha=0.5,line_alpha=0.5)
            p_k.xaxis.axis_label = f
            p_k.yaxis.axis_label = 'ki'
            p.append(p_k)
        grid = gridplot(p, ncols=2)
        show(grid)
    

    【讨论】:

    • 您可以在不同的地块上共享 CDS 对象,只要它们相同 Document。但是output_fileshow 等隐含地创建了新文档,这就是为什么原始代码会触发这种情况。
    • @Tony 这不会创建 2 个单独的 HTML 吗?
    猜你喜欢
    • 2021-12-18
    • 1970-01-01
    • 1970-01-01
    • 2017-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多