高效更新 Bokeh 中的图像图以实现交互式可视化

2024-03-31

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

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

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() 方法更新数据(尽管它没有意义,因为整个图像正在被替换),但我还没有实现任何目标性能增益。有谁知道我可以做些什么来提高此可视化的交互性?我更新图像数据时做错了什么吗?

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

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

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

还有其他建议吗?


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

为了完整起见,这里对结果进行比较。

With 0.12.3(原始帖子的版本 - 确保使用tornado

---- 总更新时间(秒):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

With 0.12.13(目前最新版本):

---- 总更新时间(秒):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']

如果所有图像都存储在单个图像的不同(长度为 1)列中,则可能会有更多边际改进。ColumnDataSource并立即更新,而不是迭代多个不同的数据源。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

高效更新 Bokeh 中的图像图以实现交互式可视化 的相关文章

随机推荐

  • viewpager 内的水平滚动视图

    我有一个 2 到 4 页的 viewpager 其中一页以表格形式显示数据 为此 我使用垂直滚动和水平滚动 由于horizo ntalscrollview和viewpager之间的冲突 有时 滚动不起作用 我想在页面向左滚动时滚动页面 当它
  • gulp browserify 捆绑时间太长

    我遇到了一个奇怪的问题 需要你的帮助来弄清楚发生了什么 我已经配置了 gulp 来构建我的测试React js在 ES6 中 我用过browserify设置 CommonJS 环境并babelify以获得更大的 ES6 支持 一切正常 只是
  • 矩阵作为应用函子,不是 Monad

    我遇到examples https stackoverflow com questions 7220436 good examples of not a functor functor applicative monad不是 Monad 的
  • 峰值检测代码

    我想计算实时信号在第一步中是否通过了一些阈值 在第一步中 我想检测真实信号是否低于这些阈值 以便检测信号中的峰值 我的Matlab代码 k 1 t 1 l 1 for i 1 length sm sm my signal if sm i g
  • 如何在Spring Security中动态切换应用程序上下文?

    我在我的 Web 应用程序中使用 Spring security 并使用 Javaconfig 最近 我们还在应用程序中添加了 Spring SAML 身份验证 并在经历了一些障碍后终于使其正常工作 在 的里面WebApplicationI
  • 您使用哪些工具在浏览器中调试 HTML/JS?

    我想收集适用于所有浏览器的最佳调试辅助工具 所以这可能是Firebug https addons mozilla org de firefox addon 1843对于 Firefox 那么你用什么来使用 IE 呢 苹果浏览器 歌剧 歌剧迷
  • C++:深度复制基类指针

    我四处搜索 似乎为了执行此操作 我需要更改我的基类 并想知道这是否是最好的方法 例如 我有一个基类 class Base 然后是一长串派生类 class Derived 1 public Base class Derived 2 publi
  • 仅将指定 div 的英文数字转换为波斯语/阿拉伯语

    我知道这个问题已经在这里回答了很多次 但我仍然没有得到确切的答案 我需要通过一些javascript将英文字母转换为波斯语 阿拉伯语字母 但不是整个页面 而是一个div或者更多 就像只针对特定类别一样 我遇到过这些代码 但不知道哪一个最好用
  • 指定形状宽度会生成错误:指定的尺寸对于当前图表类型无效

    我正在尝试将 Excel 图表另存为图像 通过整个代码 我调用了几个工作簿 查找所有工作表并保存所有图表 以下代码适用于 Excel 2007 和 2010 但由于 4 有可见的水平线和垂直线 如果我改变Round shp Width 4
  • Groupby pandas dataframe 具有相同值的两列

    我想要groupby A 和 B 中具有相同值的两列并制作cumsum基于该值所在的列 值的分组数据框示例 A B ValueA ValueB 0 b a 1 3 1 c a 2 2 2 a b 2 4 现在 如果该值位于 A 列中 则考虑
  • 从 Iron Python 生成 .NET 程序集

    我有一个 Iron Python 脚本 我想运行它 然后让 ipy 解释器输出一个可以在其他计算机上运行的程序集 我怎么做 是否有一个开关可以传递给 ipy exe 使用SharpDevelop 一种方法是使用夏普开发 http www i
  • 通过读取初始 .DBF 字节可以采用哪种标头格式?

    关于 DBF文件的第一个字节以及如何检测所使用的xbase版本 即文件其余部分的格式 我可以编译的最全面的列表是 Byte 0 x xxx x 001 0x 1 not used 0 000 0 010 0x02 FoxBASE 0 000
  • Ember.js - jQuery-masonry + 无限滚动

    我正在尝试在我的 ember 项目中实现无限滚动和砌体工作 砖石 砖块 是带有文字和图像的柱子 目前 我可以在页面初始加载时显示第一页并应用砌体 不过 我仍然需要执行 setTimeout 试图找出如何摆脱它 我还有基本的无限滚动代码 现在
  • 使用 Web 部署发布 ASP.NET MVC2 站点

    我目前使用 Web 部署 http learn iis net page aspx 346 web deploy http learn iis net page aspx 346 web deploy 发布我的 MVC2 应用程序 它曾经工
  • file_get_contents() 修改后的 HTTP 标头返回垃圾 html 输出

    以下代码用于使用 PHP 的 SIMPLETHTMLDOM 解析器提取 html include simple html dom php context stream context create array http gt array m
  • 在SAX解析期间确定根元素

    我正在使用 SAX 来解析 XML 文件 假设我希望我的应用程序only处理带有根元素 animalList 的 XML 文件 如果根节点是其他节点 SAX 解析器应该终止解析 使用 DOM 你可以这样做 Element rootEleme
  • 在 Flutter 中使用 After Effects 文件

    我知道如何导出Rive在 Flutter 应用程序中使用的 Flare 文件 但我怎样才能import Adobe 后遗症文件到 Rive 我知道可以这样做Lottie但我无法弄清楚如何准确地做到这一点 您可以轻松导入 bodymovin
  • 如何使用 Jest 和 vue/test-utils 测试输入文件

    我想使用 Jest 和 vue test utils 测试文件上传器组件 我有这个 describe show progress bar of uploading file gt const wrapper mount FileUpload
  • 如何在 lldb 中创建和使用临时 NSRange?

    NSRange 只是一个 C 结构体 我想在 Xcode 的 lldb 中的断点处创建一个临时的 专门用于 NSArray 方法objectAtIndex inRange 这是行不通的 lldb expr NSRange tmpRange
  • 高效更新 Bokeh 中的图像图以实现交互式可视化

    我正在尝试使用 Bokeh 创建多维数组的不同切片的平滑交互式可视化 切片中的数据根据 用户交互而变化 因此每秒必须更新几次 我编写了一个 Bokeh 应用程序 其中包含几个小图像图 64x64 值 来显示切片的内容 以及在用户与应用程序交