#!/usr/bin/env python
import sys
from PyQt4 import Qt
import PyQt4.Qwt5 as Qwt
try:
import numpy as np
except ImportError:
if not Qt.QCoreApplication.instance():
a = Qt.QApplication([])
Qt.QMessageBox.critical(
None,
'NumPy required',
'This example requires NumPy, but failed to import NumPy.\n'
'NumPy is available at http://sourceforge.net/projects/numpy'
)
raise SystemExit, (
'Failed to import NumPy.\n'
'NumPy is available at http://sourceforge.net/projects/numpy'
)
class MaskedData(Qwt.QwtArrayData):
def __init__(self, x, y, mask):
Qwt.QwtArrayData.__init__(self, x, y)
self.__mask = np.asarray(mask, bool)
# keep a copy of x and y for boundingRect()
self.__x = np.asarray(x)
self.__y = np.asarray(y)
# __init__()
def copy(self):
return self
# copy()
def mask(self):
return self.__mask
# mask()
def boundingRect(self):
"""Return the bounding rectangle of the data, accounting for the mask.
"""
xmax = self.__x[self.__mask].max()
xmin = self.__x[self.__mask].min()
ymax = self.__y[self.__mask].max()
ymin = self.__y[self.__mask].min()
return Qt.QRectF(xmin, ymin, xmax-xmin, ymax-ymin)
# boundingRect()
# class MaskedData
class MaskedCurve(Qwt.QwtPlotCurve):
def __init__(self, x, y, mask):
Qwt.QwtPlotCurve.__init__(self)
self.setData(MaskedData(x, y, mask))
# __init__()
def draw(self, painter, xMap, yMap, rect):
# When the array indices contains the indices of all valid data points,
# a chunks of valid data is indexed by
# indices[first], indices[first+1], .., indices[last].
# The first index of a chunk of valid data is calculated by:
# 1. indices[i] - indices[i-1] > 1
# 2. indices[0] is always OK
# The last index of a chunk of valid data is calculated by:
# 1. index[i] - index[i+1] < -1
# 2. index[-1] is always OK
indices = np.arange(self.data().size())[self.data().mask()]
fs = np.array(indices)
fs[1:] -= indices[:-1]
fs[0] = 2
fs = indices[fs > 1]
ls = np.array(indices)
ls[:-1] -= indices[1:]
ls[-1] = -2
ls = indices[ls < -1]
for first, last in zip(fs, ls):
Qwt.QwtPlotCurve.drawFromTo(self, painter, xMap, yMap, first, last)
# class MaskedCurve
def make():
demo = Qwt.QwtPlot()
demo.setTitle('Masked Data Demo')
demo.setCanvasBackground(Qt.Qt.white)
# num = 501 causes a divide by zero warning 64-bit Gentoo
x = np.linspace(-2*np.pi, 2*np.pi, num=501)
y = 1/np.sin(x)
mask = np.logical_and(y>-3.0, y<3.0)
curve = MaskedCurve(x, y, mask)
curve.attach(demo)
demo.resize(500, 300)
demo.show()
return demo
# make()
def main(args):
app = Qt.QApplication(args)
demo = make()
sys.exit(app.exec_())
# main()
# Admire
if __name__ == '__main__':
main(sys.argv)
# Local Variables: ***
# mode: python ***
# End: ***
|