python - 在 PyQtGraph 中绘制大型时间序列时使用预下采样数据

标签 python plot pyqtgraph

我需要在 PyQtGraph 中绘制大型时间序列(数百万个点)。按原样绘制它几乎是不可能的,当打开优化选项(使用 setDownsampling 进行下采样并使用 setClipToView 进行裁剪)时,它在缩小时仍然几乎不可用(仅在放大时)由于剪裁,它变得很快)。

不过我有一个想法。我可以预先对我的数据进行下采样,因为它们是静态的。然后,我可以在缩小时使用缓存的下采样数据,在放大时使用原始数据。

我怎样才能做到这一点?

最佳答案

我在一个名为 runviewer 的项目中做过类似的事情.一般的想法是,只要绘图的 x 范围发生变化,就对数据重新采样。我们使用的大概方法是:

  • 将一个方法连接到 PlotWidgetsigXRangeChanged 信号,它设置一个 bool 标志,指示数据需要重新采样。

  • 启动一个线程,每隔 x 秒(我们选择 0.5 秒)轮询一次 bool 标志,以查看是否需要对数据进行重采样。如果是,将使用您选择的算法(我们用 C 语言编写了自己的算法)对数据进行重新采样。然后将此数据发送回主线程(例如,使用 QThread 并将信号发回主线程),在主线程中调用 pyqtgraph 以更新图中的数据(注意,您只能从主线程调用 pyqtgraph 方法!)

我们使用 bool 标志将 x 范围变化事件与重采样分离。您不希望每次 x 范围发生变化时都重新采样,因为当您使用鼠标缩放时信号会被多次触发,并且您不希望生成重新采样调用队列,因为重新采样很慢,即使使用 C !

您还需要确保您的重采样线程在检测到它为 True 时立即将 bool 标志设置为 False,然后运行重采样算法。这样一来,当前重采样期间的后续 x 范围更改事件会导致后续重采样。

您也可以通过不轮询标志,而是使用某种线程事件/条件来改进这一点。

请注意,使用 Python 进行重采样非常非常慢,这就是我们选择编写重采样算法 C 并从 Python 调用它的原因。 numpy 主要在 C 中,所以会很快。但是我认为他们没有保留重采样算法的功能。大多数重采样人员所做的只是标准的下采样,即每第 N 个点取一次,但我们希望在缩小时仍然能够看到小于采样大小的特征的存在。


对性能的补充意见

我怀疑pyqtgraph内置方法的部分性能问题是降采样是在主线程中完成的。因此,必须在图形再次响应用户输入之前完成下采样。我们的方法避免了这种情况。我们的方法还将下采样发生的次数限制为最多,每 下采样所需的时间长度 + 轮询延迟 秒一次。因此,对于我们使用的延迟,我们仅每 0.5-1 秒进行一次下采样,同时保持主线程(以及 UI)响应。这确实意味着如果用户快速放大,他们可能会看到粗略采样的数据,但这在最多 2 次重采样迭代中得到纠正(因此最多延迟 1-2 秒)。此外,由于纠正时间很短,因此使用新采样数据更新/重绘通常在用户完成与 UI 的交互后进行,因此在重绘期间他们不会注意到任何无响应。

显然,我引用的次数完全取决于重采样的速度和轮询延迟!

关于python - 在 PyQtGraph 中绘制大型时间序列时使用预下采样数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30497997/

相关文章:

r - 使用plot3d在单个绘图窗口中绘制多个3D图像

python - 使用 scipy.signal.spectrogram 在 pyqtgraph 中绘制 wavfile 的频谱

python - 如何在pyqtgraph中关闭窗口

python - doc2vec.infer_vector 如何跨单词组合?

python - 美丽汤提取物循环

将 x Axis 替换为工作日标签

python - PyQtGraph 0.10.0 : auto range of PlotItem tries to scale TextItem and crashes

python - 模块在 Anaconda 提示符下工作,但在 Spyder 中不工作

python - 尝试分配循环索引时“int”对象不可迭代

python - 将 3D 图的轴放置在图表内