import time
import numpy as np
import sys
from qwt.qt.QtGui import (QApplication, QPen, QMainWindow, QGridLayout,
QTabWidget, QWidget, QTextEdit, QLineEdit, QFont,
QFontDatabase)
from qwt.qt.QtCore import Qt
import os
if os.environ.get('USE_PYQWT5', False):
USE_PYQWT5 = True
from PyQt4.Qwt5 import QwtPlot, QwtPlotCurve
else:
USE_PYQWT5 = False
from qwt import QwtPlot, QwtPlotCurve # analysis:ignore
COLOR_INDEX = None
def get_curve_color():
global COLOR_INDEX
colors = (Qt.blue, Qt.red, Qt.green, Qt.yellow, Qt.magenta, Qt.cyan)
if COLOR_INDEX is None:
COLOR_INDEX = 0
else:
COLOR_INDEX = (COLOR_INDEX + 1) % len(colors)
return colors[COLOR_INDEX]
class BMPlot(QwtPlot):
def __init__(self, title, xdata, ydata, style, symbol=None, *args):
super(BMPlot, self).__init__(*args)
self.setMinimumSize(200, 200)
self.setTitle(title)
self.setAxisTitle(QwtPlot.xBottom, 'x')
self.setAxisTitle(QwtPlot.yLeft, 'y')
for idx in range(1, 11):
curve = QwtPlotCurve()
curve.setPen(QPen(get_curve_color()))
curve.setStyle(style)
curve.setRenderHint(QwtPlotCurve.RenderAntialiased)
if symbol is not None:
curve.setSymbol(symbol)
curve.attach(self)
curve.setData(xdata, ydata*idx)
# self.setAxisScale(self.yLeft, -1.5, 1.5)
# self.setAxisScale(self.xBottom, 9.9, 10.)
self.replot()
class BMWidget(QWidget):
def __init__(self, points, *args, **kwargs):
super(BMWidget, self).__init__()
self.setup(points, *args, **kwargs)
def params(self, *args, **kwargs):
if kwargs.get('only_lines', False):
return (('Lines', None),)
else:
return (
('Lines', None),
('Dots', None),
)
def setup(self, points, *args, **kwargs):
x = np.linspace(.001, 20., points)
y = (np.sin(x)/x)*np.cos(20*x)
layout = QGridLayout()
nbcol, col, row = 2, 0, 0
for style, symbol in self.params(*args, **kwargs):
layout.addWidget(BMPlot(style, x, y, getattr(QwtPlotCurve, style),
symbol=symbol), row, col)
col += 1
if col >= nbcol:
row +=1
col = 0
self.text = QLineEdit()
self.text.setReadOnly(True)
self.text.setAlignment(Qt.AlignCenter)
self.text.setText("Rendering plot...")
layout.addWidget(self.text, row+1, 0, 1, 2)
self.setLayout(layout)
class BMText(QTextEdit):
def __init__(self, parent=None, title=None):
super(BMText, self).__init__(parent)
self.setReadOnly(True)
library = 'PyQwt5' if USE_PYQWT5 else 'PythonQwt'
wintitle = self.parent().windowTitle()
if not wintitle:
wintitle = "Benchmark"
if title is None:
title = '%s example' % wintitle
self.parent().setWindowTitle('%s [%s]' % (wintitle, library))
self.setText("""\
<b>%s:</b><br>
(base plotting library: %s)<br><br>
Click on each tab to test if plotting performance is acceptable in terms of
GUI response time (switch between tabs, resize main windows, ...).<br>
<br><br>
<b>Benchmarks results:</b>
""" % (title, library))
class BMDemo(QMainWindow):
TITLE = 'Curve benchmark'
SIZE = (1000, 800)
def __init__(self, max_n, parent=None, **kwargs):
super(BMDemo, self).__init__(parent=parent)
title = self.TITLE
if kwargs.get('only_lines', False):
title = '%s (%s)' % (title, 'only lines')
self.setWindowTitle(title)
self.tabs = QTabWidget()
self.setCentralWidget(self.tabs)
self.text = BMText(self)
self.tabs.addTab(self.text, 'Contents')
self.resize(*self.SIZE)
# Force window to show up and refresh (for test purpose only)
self.show()
QApplication.processEvents()
t0g = time.time()
self.run_benchmark(max_n, **kwargs)
dt = time.time()-t0g
self.text.append("<br><br><u>Total elapsed time</u>: %d ms" % (dt*1e3))
self.tabs.setCurrentIndex(0)
def process_iteration(self, title, widget, t0):
self.tabs.addTab(widget, title)
self.tabs.setCurrentWidget(widget)
# Force widget to refresh (for test purpose only)
QApplication.processEvents()
time_str = "Elapsed time: %d ms" % ((time.time()-t0)*1000)
widget.text.setText(time_str)
self.text.append("<br><i>%s:</i><br>%s" % (title, time_str))
def run_benchmark(self, max_n, **kwargs):
for idx in range(4, -1, -1):
points = max_n/10**idx
title = '%d points' % points
t0 = time.time()
widget = BMWidget(points, **kwargs)
self.process_iteration(title, widget, t0)
if __name__ == '__main__':
app = QApplication([])
for name in ('Calibri', 'Verdana', 'Arial'):
if name in QFontDatabase().families():
app.setFont(QFont(name))
break
kwargs = {}
for arg in sys.argv[1:]:
kwargs[arg] = True
demo = BMDemo(1000000, **kwargs)
app.exec_()