散景中的图像图的有效更新,以实现交互式可视化 [英] Efficient updates of image plots in Bokeh for interactive visualization

查看:85
本文介绍了散景中的图像图的有效更新,以实现交互式可视化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用Bokeh对多维数组的不同切片创建平滑的交互式可视化.切片中的数据根据​​用户交互而更改,因此必须每秒更新几次.我编写了一个Bokeh应用程序,其中包含几个小图像图(64x64值)以显示切片的内容,并编写了一个回调以在用户与应用程序进行交互时更新ColumnDataSources.一切正常,但是我每秒不能超过2或3帧,我希望至少获得10帧.

I'm trying to create a smooth interactive visualization of different slices of a muldimensional array using Bokeh. The data in the slices changes according to the user interaction and thus has to be updated several times per second. I have written a Bokeh app with several small image plots (64x64 values) to show the contents of the slices, and a callback to update the ColumnDataSources when the user interacts with the app. Everything works as expected but I can't get more than 2 or 3 frames per second and I would like to get at least 10 frames.

这是我的代码的简化示例,其中使用16张图像,每100毫秒定期进行一次回调,以模拟用户交互.在Mac和Linux上使用Bokeh 0.12.3和Python 2.7,两台机器上的计时几乎完全相同(每帧约300ms).

Here is a simplified sample of my code using 16 images with a periodic callback every 100ms to simulate user interaction. Using Bokeh 0.12.3 and Python 2.7 on Mac and Linux I get almost exactly the same timings (~300ms per frame) on both machines.

from __future__ import print_function, division
from random import randint
from timeit import default_timer as timer
import numpy as np

from bokeh.io import curdoc
from bokeh.layouts import gridplot
from bokeh.models import ColumnDataSource
from bokeh.plotting import figure

# Set up app and fake data
grid_size = 4
data_size = 64
names = ['d{}'.format(i) for i in range(grid_size)]
plots = [[None for _ in range(grid_size)] for _ in range(grid_size)]
sources = dict()

num_images = 16
image_data = [[np.random.rand(data_size, data_size)] for i in range(num_images)]

# Create plots and datasources
plot_size = 256
for row, row_name in enumerate(names):
    for col, c_name in enumerate(names):
        d_name = row_name + "_" + c_name
        sources[d_name] = ColumnDataSource(
            {'value': image_data[randint(0, num_images - 1)]})
        plots[row][col] = figure(plot_width=plot_size,
                                 plot_height=plot_size,
                                 x_range=(0, data_size),
                                 y_range=(0, data_size))

        plots[row][col].image('value', source=sources[d_name],
                              x=0, y=0, dw=data_size, dh=data_size,
                              palette="Viridis256")


# Updates
def update():
    global sources
    start_update, end_update = [], []
    start_time = timer()
    for row, row_name in enumerate(names):
        for col, c_name in enumerate(names):
            d_name = row_name + "_" + c_name
            new_data = dict()
            new_data['value'] = image_data[randint(0, num_images - 1)]
            start_update.append(timer())  # ----- TIMER ON
            sources[d_name].data = new_data
            end_update.append(timer())    # ----- TIMER OFF

    print("\n---- \tTotal update time (secs): {:07.5f}".format(timer() - start_time))
    print("+ \tSources update times (secs): {}".format(
           ["{:07.5f}".format(end_update[i] - s) for i,s in enumerate(start_update)]))


# Document
grid = gridplot(plots)
curdoc().add_root(grid)
curdoc().add_periodic_callback(update, 100)

我尝试为每个图只使用一个具有不同字段的数据源,并且还使用stream()方法更新数据(尽管由于替换了整个图像没有意义)并且我没有没有取得任何性能提升.有谁知道我该怎么做才能改善这种可视化的交互性?我在更新图像数据时做错了什么吗?

I've tried using only one data source with different fields for each plot, and also updating the data with the stream() method (although it doesn't make sense since the whole image is being replaced) and I haven't achieved any performance gain. Does anyone know what could I do to improve the interactivity of this visualization? Am I doing something wrong to update the image data?

我的猜测是,瓶颈是由图像数据的JSON编码/解码引起的开销,由于Bokeh开发人员似乎已经意识到并试图解决此问题,因此将来可能会有所改善.可悲的是,修复程序似乎不会很快到来.

My guess is that the bottleneck is the overhead caused by the JSON encoding/decoding of the image data, which might improve in the future since it appears that Bokeh developers are aware of this problem and trying to solve it. Sadly, it does not look like the fix is coming soon.

https://github.com/bokeh/bokeh/issues/2204

https://github.com/bokeh/bokeh/pull/5429

还有其他建议吗?

推荐答案

正如其他人所提到的,已经实现了有效的二进制数组协议.因此,答案是升级到最新版本.

As others have mentioned, an efficient binary array protocol has been implemented. So the answer is to upgrade to recent versions.

为完整起见,这里是结果的比较.

For completeness, here is a comparison of results.

使用0.12.3(原始文章的版本—确保使用龙卷风<4.5):

With 0.12.3 (the version from the original post — make sure to use tornado < 4.5):

----总更新时间(秒):0.14389 +来源更新时间(秒):['0.00943','0.00962','0.01100','0.00908','0.00004','0.00975','0.00984','0.00997','0.00946','0.00926',' 0.00912","0.00898","0.00900","0.00908","0.00999","0.01014"] ^ C

---- Total update time (secs): 0.14389 + Sources update times (secs): ['0.00943', '0.00962', '0.01100', '0.00908', '0.00004', '0.00975', '0.00984', '0.00997', '0.00946', '0.00926', '0.00912', '0.00898', '0.00900', '0.00908', '0.00999', '0.01014'] ^C

使用0.12.13(当前的最新版本):

With 0.12.13 (the most recent version as of this time):

----总更新时间(秒):0.01999 +来源更新时间(秒):['0.00157','0.00231','0.00131','0.00143','0.00114','0.00123','0.00109','0.00118','0.00116','0.00102',' 0.00113','0.00118','0.00099','0.00099','0.00104','0.00104']

---- Total update time (secs): 0.01999 + Sources update times (secs): ['0.00157', '0.00231', '0.00131', '0.00143', '0.00114', '0.00123', '0.00109', '0.00118', '0.00116', '0.00102', '0.00113', '0.00118', '0.00099', '0.00099', '0.00104', '0.00104']

如果将所有图像存储在单个ColumnDataSource的不同(长度1)列中并立即更新,而不是遍历几个不同的数据源,则可能会有更大的改进.

There is probably even more marginal improvement possible if all of the images are stored in different (length 1) columns of a single ColumnDataSource and updated at once, rather than iterating over several different data sources.

这篇关于散景中的图像图的有效更新,以实现交互式可视化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆