Using Qt Charts (PyQtChart) to plot curves efficiently in Python!

Pierre Raybaut edited this page Aug 5, 2016 · 3 revisions

I've just discovered an interesting alternative to PyQwt for plotting curves efficiently. That is Qt Charts, a module of Qt which exists at least since 2012 according to PyQtChart changelog (PyQtChart is a set of Python bindings for Qt Charts library).

Here is a simple example which is as efficient as PyQwt (and much more efficient than PythonQwt):

# -*- coding: utf-8 -*-
#
# Licensed under the terms of the MIT License
# Copyright (c) 2015 Pierre Raybaut

"""
Simple example illustrating Qt Charts capabilities to plot curves with 
a high number of points, using OpenGL accelerated series
"""

from PyQt5.QtChart import QChart, QChartView, QLineSeries
from PyQt5.QtGui import QPolygonF, QPainter
from PyQt5.QtWidgets import QMainWindow

import numpy as np


def series_to_polyline(xdata, ydata):
    """Convert series data to QPolygon(F) polyline
    
    This code is derived from PythonQwt's function named 
    `qwt.plot_curve.series_to_polyline`"""
    size = len(xdata)
    polyline = QPolygonF(size)
    pointer = polyline.data()
    dtype, tinfo = np.float, np.finfo  # integers: = np.int, np.iinfo
    pointer.setsize(2*polyline.size()*tinfo(dtype).dtype.itemsize)
    memory = np.frombuffer(pointer, dtype)
    memory[:(size-1)*2+1:2] = xdata
    memory[1:(size-1)*2+2:2] = ydata
    return polyline    

    
class TestWindow(QMainWindow):
    def __init__(self, parent=None):
        super(TestWindow, self).__init__(parent=parent)
        self.ncurves = 0
        self.chart = QChart()
        self.chart.legend().hide()
        self.view = QChartView(self.chart)
        self.view.setRenderHint(QPainter.Antialiasing)
        self.setCentralWidget(self.view)
        
    def set_title(self, title):
        self.chart.setTitle(title)

    def add_data(self, xdata, ydata, color=None):
        curve = QLineSeries()
        pen = curve.pen()
        if color is not None:
            pen.setColor(color)
        pen.setWidthF(.1)
        curve.setPen(pen)
        curve.setUseOpenGL(True)
        curve.append(series_to_polyline(xdata, ydata))
        self.chart.addSeries(curve)
        self.chart.createDefaultAxes()
        self.ncurves += 1


if __name__ == '__main__':
    import sys
    from PyQt5.QtWidgets import QApplication
    from PyQt5.QtCore import Qt
    app = QApplication(sys.argv)

    window = TestWindow()

    npoints = 1000000
    xdata = np.linspace(0., 10., npoints)
    window.add_data(xdata, np.sin(xdata), color=Qt.red)
    window.add_data(xdata, np.cos(xdata), color=Qt.blue)
    window.set_title("Simple example with %d curves of %d points "\
                     "(OpenGL Accelerated Series)"\
                     % (window.ncurves, npoints))
    window.setWindowTitle("Simple performance example")
    window.show()
    window.resize(500, 400)

    sys.exit(app.exec_())
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.