【问题标题】:Strange behaviour when function returns NdOverlay to DynamicMap函数将 NdOverlay 返回给 DynamicMap 时的奇怪行为
【发布时间】:2020-03-24 16:00:26
【问题描述】:

当有一个函数生成指向 DynamicMap 的 NdOverlay 点时,我遇到了一些非常奇怪的事情,其中​​该函数与面板小部件相关联(我认为面板小部件并不重要)。

下面的代码是一个产生预期行为的工作示例。每当您更改小部件值时,都会生成一个新图,其中包含两组重叠的点,具有不同的颜色和各自的图例条目。图片如下代码所示。

a_widget = pn.widgets.Select(name='A', options=[1,2,3,4])
b_widget = pn.widgets.IntSlider(name='B', start=10, end=20, value=10)
widget_box = pn.WidgetBox(a_widget, b_widget, align='center')

@pn.depends(a=a_widget.param.value, b=b_widget.param.value)
def get_points(a, b):
    return hv.NdOverlay({x: hv.Points(np.random.rand(10,10)) for x in range(1,3)})

points = hv.DynamicMap(get_points)

pn.Row(widget_box, points)

下面显示的第二个示例旨在证明在某些情况下您可能只想简单地返回一个空图,并且我在此示例中所做的方式与此示例中的方式相同: http://holoviews.org/gallery/demos/bokeh/box_draw_roi_editor.html#bokeh-gallery-box-draw-roi-editora == 1 时,这段代码的结果是一个空图,但当a 的值不是1 时,结果很奇怪,如下图所示。

  1. 所有点都具有相同的颜色
  2. 例如,在更改滑块时,某些点会被冻结并且永远不会更改,而在上述工作示例中并非如此。
a_widget = pn.widgets.Select(name='A', options=[1,2,3,4])
b_widget = pn.widgets.IntSlider(name='B', start=10, end=20, value=10)
widget_box = pn.WidgetBox(a_widget, b_widget, align='center')

@pn.depends(a=a_widget.param.value, b=b_widget.param.value)
def get_points(a, b):
    if a == 1:
        return hv.NdOverlay({None: hv.Points([])})
    else:
        return hv.NdOverlay({x: hv.Points(np.random.rand(10,10)) for x in range(1,3)})

points = hv.DynamicMap(get_points)

pn.Row(widget_box, points)

【问题讨论】:

  • 嗨 Martin,最好在此处发布指向您的 SO 问题的链接:gitter.im/pyviz/pyviz,以便全息视图的开发人员可以帮助您解决这个问题(和其他问题)
  • 嗨。谢谢你的提示。我加入了房间并寻求帮助:)

标签: python holoviews pyviz


【解决方案1】:

虽然我无法解决NdOverlay 观察到的问题,但可以在Overlay 的帮助下创建包含或不包含内容的图。

由于您的代码中从未使用过b_widget,因此为简单起见,我将其删除。

a_widget = pn.widgets.Select(name='A', options=[1,2,3,4])
widget_box = pn.WidgetBox(a_widget, align='center')

@pn.depends(a=a_widget.param.value)
def get_points(a):
    images = []
    if a == 3:
        images.append(hv.Points(np.random.rand(10,10), label='None'))
    else:
        for x in range(1,3):
            images.append(hv.Points(np.random.rand(10,10), label=str(x)))
    return hv.Overlay(images)

points = hv.DynamicMap(get_points)

pn.Row(widget_box, points)

documentation for NdOverlay 中描述的如何使用 NdOverlay 的方式与您的方法不同,这可能是观察到问题的原因。


无论如何,为了缩小代码的哪一部分对观察到的问题负责,我删除了所有不需要重现它的代码。

为了清楚起见,我重命名了 a 的值,并且我还确保提供了 a 的起始值。

在测试代码时发现,if-else-statement 并不重要,所以我也删除了它。

为了确保变量的行为符合预期,我添加了一些 print-statements。

这给出了以下最小可重现示例:

a_widget = pn.widgets.Select(name='A', value='Test', options=['Test','Test1', 'Test2'])

@pn.depends(a=a_widget.param.value)
def get_points(a):
    dict_ = {}
    dict_[str(a)] = hv.Points(np.random.rand(10,10))

    print(dict_)
    overlay = hv.NdOverlay(dict_)
    print(overlay)

    return overlay

points = hv.DynamicMap(get_points)

# using the server approach here to see the outpout of the
# print-statements
app = pn.Row(a_widget, points)
app.app() 

运行此代码并在选择小部件中选择不同选项时,发现选项 Test 未更新,一旦选择了选项 Test1Test3 之一。

当我们像这样改变第一行的默认值时

a_widget = pn.widgets.Select(name='A', value='Test2', options=['Test','Test1', 'Test2'])

现在Test2 没有正确更新。

所以看起来这是DynamicMap 使用NdOverlay 的问题。 所以我建议你将此问题报告给开发人员(如果尚未完成),要么等待新版本发布,要么使用其他方法(例如,如上所示)。

【讨论】:

  • b_widget is used...(?) 即便如此,我的示例与我在问题中链接到的 holoviews.org 上的示例非常相似。
  • @Martin Rindarøy:我已经更新了我的答案。它现在包含基于您的代码和链接示例的部分。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-22
  • 1970-01-01
  • 2013-10-28
  • 2012-06-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多