2

更新25-09-2018

为了为这个问题创建一个更简单的演示(发布在这里:http: //jsfiddle.net/bLgj4vc7/3/),我终于发现了问题的根本原因。我也设法解决了这个问题,我已将其发布为答案。


我在我的 web 应用程序中使用独立的 bokehjs。我的问题是渲染器没有用更新的数据源更新它的行字形(或者至少这对我来说是这样的问题)。

这个 jsfiddle: http: //jsfiddle.net/uwnqcotg/8/演示了这个问题。请忽略其中的任何不良编码约定;这是一个快速的一次性演示。

在小提琴中,情节加载了一个数据系列,渲染得很好。该图可以通过两种方式更新:

  1. Update Plot Once By Overwriting CDS.data Object一次性覆盖 ColumnDataSource.data 对象,从而遵循保持相同列长度的散景原则。

  2. Start Stream With CDS.stream使用 ColumnDataSource.stream() 并使用随机生成的增量数据序列定期更新绘图。

在第一种方法中,字形看起来正在更新 - 轴肯定会根据控制台中打印的数据序列进行更新以供参考。但是,绘制的字形和数据系列显示不匹配。对我来说,它看起来像初始化绘图时绘制的字形只是重新调整到新轴,尽管我不能确定。

在第二种方法中,轴再次更新,但字形没有。同样,最初绘制的字形似乎重新调整到新的轴范围。此外,rollover由于渲染器只是不断累积数据,因此似乎忽略了 attr。

总的来说,我的观察是,在初始化期间提供给渲染器的任何数据都被正确绘制,但任何后续的流式更新甚至覆盖都没有。虽然我可能在这里错了。

另一方面,在我和散景之间,我倾向于相信我做错了什么或错过了什么。那是什么?

4

1 回答 1

0

正如问题中更新的那样,为了创建一个发布在这里的更简单的演示http://jsfiddle.net/bLgj4vc7/3/,我遇到了这个问题的根本原因:

看起来 bokehjs 有一个错误,即渲染器一旦使用一定长度的数据集初始化,即使在数据集中的后续更新中也会坚持该长度。换句话说,

  1. 如果使用空数据集初始化渲染器{x:[], y:[]},即使稍后使用填充的数据集更新 renderer.data_source,渲染器也会保持零长度,并且不会在绘图上绘制任何内容。
  2. 对于长度为 5 的初始数据集,只会从任何后续更新中读取前 5 个点,并且相应地更新字形。其余的点不被承认。

我不知道问题是渲染器的读取是否超出了初始长度,或者是否存在但未能在绘图上重绘字形。肯定会ColumnDataSource正确更新。

此答案中链接的小提琴最能说明问题。

那么解决方案是什么?目前,此解决方法:使用填充NaNs 的数据集初始化渲染器,其长度等于或大于您要为单个数据系列绘制的最大数据点数。

因此,如果在一行字形中,我希望绘制最多 100 个数据点,那么:

const plot = Bokeh.Plotting.figure()

const maxDataPoints = 100 // maximum number of points I want for this glyph
const emptyData = Array().fill().map(_ => NaN)
const cds = new Bokeh.ColumnDataSource({x: emptyData, y: emptyData})  
const renderer = plot.line({field: 'x'}, {field: 'y'}, {source: cds, line_width: 2})

// now any subsequent updates to datasource of renderer will update its glyph on the plot.
renderer.data_source.data = {
  x: dataLengthLessOrEqualToMaxDataPoints.x,
  y: dataLengthLessOrEqualToMaxDataPoints.y
}

当然,我认为 bokehjs 的这种行为要么是一个错误,要么是我在初始化中遗漏了一个未记录的步骤。无论哪种方式,都值得在 github 上创建一个问题:https ://github.com/bokeh/bokeh/issues/8277

于 2018-09-25T17:23:30.313 回答