PyQwt QwtPlot 慢

Posted

技术标签:

【中文标题】PyQwt QwtPlot 慢【英文标题】:PyQwt QwtPlot Slow 【发布时间】:2013-09-12 15:56:46 【问题描述】:

我正在使用 PyQwt 绘制一个适度的数据集(666528 点),它需要非常长的时间来重新绘制缩放等。

ncalls  tottime  percall  cumtime  percall filename:lineno(function)
    1    2.115    2.115    2.116    2.116 built-in method replot

我期待接近 100 毫秒而不是 2.1 秒

看起来其他人在使用 Qwt 时也遇到了同样的问题,但解决方案建议都与 Qwt6 中可用的选项有关,但只有 v5 的 python 绑定。 因此,我将 Qwt 版本 5.2.1 与 Python 2.7.2 一起使用。

在 Qwt6 中,建议为 ClipPolygons、FilterPoints、MinimizeMemory、ImageBuffer 适当地设置绘制属性。据我了解,问题在于绘制所有大致映射到相同像素的点,并且油漆一遍又一遍地重新绘制相同的像素,而不仅仅是绘制一次像素。

我尝试设置一些我在绘图曲线上可用的属性,如下所示,但速度没有明显差异。

def addSignals(self, signals):
    for signal in signals:
        curve = QwtPlotCurve(signal.name())
        curve.setPaintAttribute(QwtPlotCurve.PaintFiltered, False)
        curve.setPaintAttribute(QwtPlotCurve.ClipPolygons, True)
        curve.setData(signal.x(), signal.y())
        curve.setRenderHint(QwtPlotItem.RenderAntialiased)
        curve.setPen(QPen(Qt.cyan))
        curve.attach(self)
    self.replot()

通过 setData 加载到 PlotCurve 对象中的数据是来自信号对象的 numpy 数组。并且显示的方法附加到子类 QwtPlot 对象

我是否缺少 Qwt 版本中可用的选项,或者这仅在 v6 中可用? 我有哪些加快速度的选择?

谢谢

【问题讨论】:

【参考方案1】:

好吧,对于您的用例,Qwt 5 应该不会慢很多。

更重要的是使用什么版本的 Qt 以及背后的图形系统类型:f.e Qt4/X11 是硬件加速的。

但至少你的代码的一个显而易见的性能问题是抗锯齿:

你可以在深度放大时启用它(在这种情况下它没有问题,因为几乎所有的多边形都被剪掉了),但是当显示超过 600000 行时它完全没有意义。

显示一个包含许多点的数据集(> 600000 在 QPainter 方面不再适中)背后的总体思路是为不同的缩放级别实现多个数据集。在这里 QwtPlotWeedingFitter 可以提供帮助(不要在 replot 中使用它!) - 但是你需要 Qwt6。

但最好在 Qwt 支持频道上询问,我不经常在这里阅读。

【讨论】:

我使用的是 Qt 4.6.3 版,你对抗锯齿很感兴趣。一旦我删除了那条线,它就运行得很好!谢谢【参考方案2】:

Qt 4.7 是关于性能改进的,所以你应该考虑升级!

AFAIR Qt 4.6 中的光栅绘制引擎(您使用 QWS 或 Windows 的引擎)与 QPainter::drawPolyline() 存在严重的性能问题,其中时间增加超过线性(猜测一些算法 O(n*n ) 涉及) 与点的数量 - 对于有 600000 条线的曲线来说,这会极大地打击你。

您的用例中最快的选项是 Qt4/X11,因为它是真正的硬件加速。请注意,对于 Qt 4.8,您必须手动启用“本机”图形系统(在它成为 X11 上的默认设置之前)并且 Qt5/X11 不再加速。

使用 C++ 时,您可以使用 Qwt 6.1,您还可以选择基于 OpenGL 的画布。我还有一些通过离线 QGLPixelBuffer 呈现像素图的代码,很可能将其放入 Qwt 6.2。

【讨论】:

以上是关于PyQwt QwtPlot 慢的主要内容,如果未能解决你的问题,请参考以下文章

通过鼠标使用 PyQwt 从画布上记录曲线/多边形

qwtplot:重新绘制时没有情节更新

qwt plot - 如何根据鼠标光标进行缩放

PyQwt 反转轴(或,设置 PyQwt 属性)

求教:使用qwtPlot画曲线,只能用setData吗? 我希望每次画一个点,依次描点画线,形成动态的曲线。

使用qwt画图时如何获得一条线的最右边的宽度