实时多线图更新性能出色

时间:2019-09-30 12:48:38

标签: python bokeh graphing

我目前正在使用Bokeh来呈现multi_line绘图,该绘图有几条静态线和一条线是实时更新的。仅用很少的几行就可以很好地运行,但是,取决于行的分辨率(通常每行2000-4000点),当图中有50条以上的行时,刷新率会大大下降。当时浏览器的CPU使用率很高。

这是情节初始化和实时更新触发的方式:

    figure_opts = dict(plot_width=750,
                        plot_height=750,
                        x_range=(0, dset_size),
                        y_range=(0, np.iinfo(dtype).max),
                        tools='pan,wheel_zoom')

    line_opts = dict(
        line_width=5, line_color='color', line_alpha=0.6,
        hover_line_color='color', hover_line_alpha=1.0,
        source=profile_lines
    )

    profile_plot = figure(**figure_opts)
    profile_plot.toolbar.logo = None
    multi_line_plot = profile_plot.multi_line(xs='x', ys='y', **line_opts)
    profile_plot.xaxis.axis_label = "x"
    profile_plot.yaxis.axis_label = "y"

    ds = multi_line_plot.data_source

    def update_live_plot():
        random_arr = np.random.random_integers(65535 * (i % 100) / (100 + 100 / 4), 65535 * (i % 100 + 1) / 100, (2048))
        profile = random_arr.astype(np.uint16)
        if profile is not None:
            profile_lines["x"][i] = x
            profile_lines["y"][i] = profile
            profile_lines["color"][i] = Category20_20[0]
            ds.data = profile_lines

    doc.add_periodic_callback(update_live_plot, 100)

有什么方法可以使这种效果更好? 例如,是否可能只更新需要更新的一行而不是ds.data = profile_lines

编辑:需要更新的一行必须完整更新。即我不是在一端流数据,而是我有一套全新的2000-4000值并想显示这些值,而不是旧的 live 行。 当前, live 行是i字典数组中profile_lines上的元素。

1 个答案:

答案 0 :(得分:1)

很幸运,使用CDS patch方法可以完成所有元素的更新,同时保持相同的长度。 (在这里,流式传输无济于事,因为流式传输到multi_line的CDS的末尾意味着添加整个新行,而流式传输到每个子行的末尾的另一种情况并没有很好的解决方案全部。)

存储库中有一个patch_app.py example,其中显示了如何使用patch更新multi_line的一行。该示例仅更新直线中的单个点,但是可以使用切片一次更新整条直线:

source.patch({ 'ys' : [([i, slice(None)], new_y)]})

只要source.data['ys']与旧行的长度相同,这将更新new_y中的第i行。