如何通过散景图中的选择更改来替换面板的一部分?

问题描述 投票:1回答:1

通常,我可以通过popinsert替换面板的一部分,这会自动更新任何现有的面板。但是,如果这些是通过bokeh selected.on_change回调触发的,现有面板不会更新。

例如,在JupyterLab工作中运行以下内容

from bokeh.plotting import figure
from bokeh.sampledata.iris import flowers
from bokeh.models import ColumnDataSource
import panel as pn


pn.extension()

def create_figure():
    src = ColumnDataSource(flowers)
    p = figure(height=200, width=200, tools='box_select')
    p.circle("petal_length", "petal_width", source=src)
    return p

pnl = pn.panel(pn.Row(create_figure, create_figure))
pnl

当我在下一个单元格中运行以下命令时,显示的面板将按预期更新:

pnl.pop(0)
pnl.insert(0, figure)

但是,当列数据源的选择发生更改时,如果我通过回调执行相同的操作,则面板不会更新,因为我在图中选择了数据点:

def replace_plot(attr, old, new):
    pnl.objects.pop(0)
    pnl.objects.insert(0, figure)

def create_figure():
    src = ColumnDataSource(flowers)
    p = figure(height=200, width=200, tools='box_select')
    p.circle("petal_length", "petal_width", source=src)
    src.selected.on_change('indices', replace_plot)
    return p

pnl = pn.panel(pn.Row(create_figure, create_figure))
pnl

起作用的是用新列表替换整个pnl.objects

def replace_plot(attr, old, new):
    pnl.objects = [figure]

[奇怪的是,这仅在我调用pnl.show()在新的浏览器选项卡中显示面板时才有效,在笔记本中,我需要在新的单元格中再次显示面板以查看更新。我尝试通过索引替换objects列表中的单个项目,但是其工作原理与popinsert相同,面板没有自动更新。

是否可以通过selected.on_change回调替换面板的一部分并使其自动刷新(最好在笔记本内部,但也可以通过show起作用)]

版本:

-----
bokeh       2.0.1
pandas      1.0.3
panel       0.9.5
-----
IPython             6.5.0
jupyter_client      5.2.3
jupyter_core        4.6.3
jupyterlab          2.1.0
notebook            5.6.0
-----
Python 3.7.6 | packaged by conda-forge | (default, Mar 23 2020, 23:03:20) [GCC 7.3.0]
Linux-5.6.13-arch1-1-x86_64-with-arch
4 logical CPU cores
-----
Session information updated at 2020-05-21 18:38
bokeh pyviz holoviz panel-pyviz
1个回答
0
投票

原来这是面板中的错误,现在可以在https://github.com/holoviz/panel/issues/1368处进行跟踪。目前,以下代码段可解决该问题:

from panel.io.notebook import push

def replace_plot(attr, old, new):
    for ref in pnl._models:
        _, _, doc, comm = pn.state._views[ref]
        doc.hold()
        pnl[0] = 1
        push(doc, comm)
    for ref in pnl._models:
        _, _, doc, comm = pn.state._views[ref]
        doc.unhold()
© www.soinside.com 2019 - 2024. All rights reserved.