实时 multi_line 图形更新,性能不错

Realtime multi_line graph updates at decent performance

我目前正在使用 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?

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

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

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

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

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