具有两个流的 Holoviews DynamicMap 区域或曲线显示错误的图表

Holoviews DynamicMap Area or Curve with two streams is showing wrong chart

我想将 HoloViews DynamicMap 与一个小部件一起使用 select 两条曲线的数据,以及一个控制曲线是单独显示还是作为填充区域显示的小部件。它几乎可以工作,但有时会显示错误的数据,具体取决于操作小部件的顺序。

下面的代码片段演示了这个问题,如果 运行 在 Jupyter 笔记本中。它创建两个相同的 DynamicMaps 以显示它们如何与小部件不同步。

代码片段

    import holoviews as hv
    import numpy as np
    import panel as pn
    
    pn.extension()
    
    # Make two binary widgets to control whether chart
    # data is high or low, and whether chart shows
    # an area fill or just a pair of lines.
    check_boxes = {name: pn.widgets.Checkbox(value=False, name=name) \
                   for name in ["higher", "fill"]}
    
    # Data for charts.
    xvals = [0.10, 0.90]
    yvals_high = [1, 1.25]
    yvals_low = [0.25, 0.40]
    
    # Declare horizontal and vertical dimensions to go on charts.
    xdim = hv.Dimension("x", range=(-0.5, 1.5), label="xdim")
    ydim = hv.Dimension("y", range=(0, 2), label="ydim")
    
    def make_plot(higher, fill):
        """Make high or low, filled area or line plot"""
        yvals_line1 = np.array(yvals_high if higher else yvals_low)
        yvals_line2 = 1.2*yvals_line1
            
        if fill:
            # Make filled area plot with x series and two y series.
            area_data = (xvals, yvals_line1, yvals_line2)
            plot = hv.Area(area_data,
                           kdims=xdim, 
                           vdims=[ydim, ydim.clone("y.2")])
            plot = hv.Overlay([plot])  # DMap will want an overlay.
        else:
            # Make line plot with x series and y series.
            line_data_low = (xvals, yvals_line1)
            line_data_high = (xvals, yvals_line2)
    
            plot = hv.Curve(line_data_low, 
                            kdims=xdim, 
                            vdims=ydim) \
                * hv.Curve(line_data_high, 
                            kdims=xdim, 
                            vdims=ydim)
        return plot
    
    # Map combinations of higher and fill to corresponding charts.
    chart_dict = {(higher, fill): make_plot(higher, fill) \
                  for higher in [False,True] for fill in [False,True]}
    
    def chart_func(higher, fill):
        """Return chart from chart_dict lookup"""
        return chart_dict[higher, fill]
    
    # Make two DynamicMaps linked to the check boxes.
    dmap1 = hv.DynamicMap(chart_func, kdims=["higher", "fill"], streams=check_boxes)
    dmap2 = hv.DynamicMap(chart_func, kdims=["higher", "fill"], streams=check_boxes)
    
    # Show the check boxes, and one of the DMaps.
    widget_row = pn.Row(*check_boxes.values(), width=150)
    dmap_row = pn.Row(dmap1, align='start')
    
    layout = pn.Column(widget_row,
                        dmap_row)
    display(layout)
    ## Optionally use following line to launch a server, then toggle widgets.
    #layout.show()
    
    
    # Toggle 'fill' and then 'higher', in that order.  
    # Both DMaps should track widgets...
    check_boxes["fill"].value = True
    check_boxes["higher"].value = True
    
    # Show the other DMap, which displays correctly given the current widgets.
    dmap_row.append(dmap2)
    
    # But first dmap (left) is now showing an area in wrong location.

笔记本显示器

更多小部件切换

下面的代码片段可以 运行 紧接着在另一个单元格中。生成的笔记本显示在代码片段下方的图像中。

# Toggle 'fill' and then 'higher' again, in that order.  
# Both DMaps should track widgets...
check_boxes["fill"].value = False
check_boxes["higher"].value = False

# But now the second DMap shows lines in wrong location.

我是不是用错了方法?

感谢详细、可重现的报告!

在 运行 你的例子之后,我注意到两件事:

  1. 开始时从 pn.extension 切换到 hv.extension 似乎解决了我在使用面板扩展时也观察到的奇怪行为。您能否确认使用 holoviews 扩展程序时一切正常?

  2. 我想知道为什么您的 DynamicMap 通过 chart_dictchart_func 工作,而您可以在 [=直接12=]s,不加修改。

如果您可以确认使用的扩展程序改变了行为,您可以就此提交 issue 吗?谢谢!