具有两个流的 Holoviews DynamicMap 区域或曲线显示错误的图表
Holoviews DynamicMap Area or Curve with two streams is showing wrong chart
我想将 HoloViews DynamicMap 与一个小部件一起使用 select 两条曲线的数据,以及一个控制曲线是单独显示还是作为填充区域显示的小部件。它几乎可以工作,但有时会显示错误的数据,具体取决于操作小部件的顺序。
下面的代码片段演示了这个问题,如果 运行 在 Jupyter 笔记本中。它创建两个相同的 DynamicMaps 以显示它们如何与小部件不同步。
- 对于此演示,如果 'fill',则会显示面积图。否则,两个 Curve 元素显示同一区域的顶部和底部边界。
- 如果'higher',区域或曲线沿垂直轴向上移动(更高的 y 值)。
- 首先显示一张动态地图。然后,代码片段依次切换 'fill' 和 'higher' 的小部件(或者,用户可以手动切换小部件)。 DynamicMap应该在较高位置显示填充区域,但实际上在较低位置显示填充区域。代码片段下方的图像在左侧显示了这个不正确的 DynamicMap。
- 第二个 DynamicMap(显示在右侧)在切换小部件后添加到显示中。它会正确显示与当时小部件状态对应的图表。
代码片段
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.
笔记本显示器
更多小部件切换
下面的代码片段可以 运行 紧接着在另一个单元格中。生成的笔记本显示在代码片段下方的图像中。
- 此处的代码再次切换小部件,'fill' 和 'higher',按此顺序(或者,用户可以手动切换小部件)。
- 左边DynamicMap正确显示了widget此时状态对应的图表,即下方两行。
- 右边的动态地图错误地显示了较高位置的两条线。
# 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.
我是不是用错了方法?
感谢详细、可重现的报告!
在 运行 你的例子之后,我注意到两件事:
开始时从 pn.extension
切换到 hv.extension
似乎解决了我在使用面板扩展时也观察到的奇怪行为。您能否确认使用 holoviews 扩展程序时一切正常?
我想知道为什么您的 DynamicMap
通过 chart_dict
和 chart_func
工作,而您可以在 [=直接12=]s,不加修改。
如果您可以确认使用的扩展程序改变了行为,您可以就此提交 issue 吗?谢谢!
我想将 HoloViews DynamicMap 与一个小部件一起使用 select 两条曲线的数据,以及一个控制曲线是单独显示还是作为填充区域显示的小部件。它几乎可以工作,但有时会显示错误的数据,具体取决于操作小部件的顺序。
下面的代码片段演示了这个问题,如果 运行 在 Jupyter 笔记本中。它创建两个相同的 DynamicMaps 以显示它们如何与小部件不同步。
- 对于此演示,如果 'fill',则会显示面积图。否则,两个 Curve 元素显示同一区域的顶部和底部边界。
- 如果'higher',区域或曲线沿垂直轴向上移动(更高的 y 值)。
- 首先显示一张动态地图。然后,代码片段依次切换 'fill' 和 'higher' 的小部件(或者,用户可以手动切换小部件)。 DynamicMap应该在较高位置显示填充区域,但实际上在较低位置显示填充区域。代码片段下方的图像在左侧显示了这个不正确的 DynamicMap。
- 第二个 DynamicMap(显示在右侧)在切换小部件后添加到显示中。它会正确显示与当时小部件状态对应的图表。
代码片段
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.
笔记本显示器
更多小部件切换
下面的代码片段可以 运行 紧接着在另一个单元格中。生成的笔记本显示在代码片段下方的图像中。
- 此处的代码再次切换小部件,'fill' 和 'higher',按此顺序(或者,用户可以手动切换小部件)。
- 左边DynamicMap正确显示了widget此时状态对应的图表,即下方两行。
- 右边的动态地图错误地显示了较高位置的两条线。
# 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.
我是不是用错了方法?
感谢详细、可重现的报告!
在 运行 你的例子之后,我注意到两件事:
开始时从
pn.extension
切换到hv.extension
似乎解决了我在使用面板扩展时也观察到的奇怪行为。您能否确认使用 holoviews 扩展程序时一切正常?我想知道为什么您的
DynamicMap
通过chart_dict
和chart_func
工作,而您可以在 [=直接12=]s,不加修改。
如果您可以确认使用的扩展程序改变了行为,您可以就此提交 issue 吗?谢谢!