From 4cec9ff044292a408a3a442f67b289d5e3df52cb Mon Sep 17 00:00:00 2001 From: Luke Campagnola Date: Mon, 11 Feb 2013 21:45:41 -0500 Subject: [PATCH] Added ErrorBarItem to repository --- examples/ErrorBarItem.py | 30 ++++++ pyqtgraph/graphicsItems/ErrorBarItem.py | 133 ++++++++++++++++++++++++ 2 files changed, 163 insertions(+) create mode 100644 examples/ErrorBarItem.py create mode 100644 pyqtgraph/graphicsItems/ErrorBarItem.py diff --git a/examples/ErrorBarItem.py b/examples/ErrorBarItem.py new file mode 100644 index 00000000..9c1bbf1e --- /dev/null +++ b/examples/ErrorBarItem.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +""" +Demonstrates basic use of ErrorBarItem + +""" + +import initExample ## Add path to library (just for examples; you do not need this) + +import pyqtgraph as pg +from pyqtgraph.Qt import QtGui +import numpy as np + +import pyqtgraph as pg +import numpy as np + +x = np.arange(10) +y = np.arange(10) %3 +top = np.linspace(1.0, 3.0, 10) +bottom = np.linspace(2, 0.5, 10) + +plt = pg.plot() +err = pg.ErrorBarItem(x=x, y=y, top=top, bottom=bottom, beam=0.5) +plt.addItem(err) +plt.plot(x, y, symbol='o') + +## Start Qt event loop unless running in interactive mode or using pyside. +if __name__ == '__main__': + import sys + if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'): + QtGui.QApplication.instance().exec_() diff --git a/pyqtgraph/graphicsItems/ErrorBarItem.py b/pyqtgraph/graphicsItems/ErrorBarItem.py new file mode 100644 index 00000000..ccb38774 --- /dev/null +++ b/pyqtgraph/graphicsItems/ErrorBarItem.py @@ -0,0 +1,133 @@ +import pyqtgraph as pg +from pyqtgraph.Qt import QtGui, QtCore +from .GraphicsObject import GraphicsObject + +__all__ = ['ErrorBarItem'] + +class ErrorBarItem(GraphicsObject): + def __init__(self, **opts): + """ + Valid keyword options are: + x, y, height, width, top, bottom, left, right, beam, pen + + x and y must be numpy arrays specifying the coordinates of data points. + height, width, top, bottom, left, right, and beam may be numpy arrays, + single values, or None to disable. All values should be positive. + + If height is specified, it overrides top and bottom. + If width is specified, it overrides left and right. + """ + GraphicsObject.__init__(self) + self.opts = dict( + x=None, + y=None, + height=None, + width=None, + top=None, + bottom=None, + left=None, + right=None, + beam=None, + pen=None + ) + self.setOpts(**opts) + + def setOpts(self, **opts): + self.opts.update(opts) + self.path = None + self.update() + self.informViewBoundsChanged() + + def drawPath(self): + p = QtGui.QPainterPath() + + x, y = self.opts['x'], self.opts['y'] + if x is None or y is None: + return + + beam = self.opts['beam'] + + + height, top, bottom = self.opts['height'], self.opts['top'], self.opts['bottom'] + if height is not None or top is not None or bottom is not None: + ## draw vertical error bars + if height is not None: + y1 = y - height/2. + y2 = y + height/2. + else: + if bottom is None: + y1 = y + else: + y1 = y - bottom + if top is None: + y2 = y + else: + y2 = y + top + + for i in range(len(x)): + p.moveTo(x[i], y1[i]) + p.lineTo(x[i], y2[i]) + + if beam is not None and beam > 0: + x1 = x - beam/2. + x2 = x + beam/2. + if height is not None or top is not None: + for i in range(len(x)): + p.moveTo(x1[i], y2[i]) + p.lineTo(x2[i], y2[i]) + if height is not None or bottom is not None: + for i in range(len(x)): + p.moveTo(x1[i], y1[i]) + p.lineTo(x2[i], y1[i]) + + width, right, left = self.opts['width'], self.opts['right'], self.opts['left'] + if width is not None or right is not None or left is not None: + ## draw vertical error bars + if width is not None: + x1 = x - width/2. + x2 = x + width/2. + else: + if left is None: + x1 = x + else: + x1 = x - left + if right is None: + x2 = x + else: + x2 = x + right + + for i in range(len(x)): + p.moveTo(x1[i], y[i]) + p.lineTo(x2[i], y[i]) + + if beam is not None and beam > 0: + y1 = y - beam/2. + y2 = y + beam/2. + if width is not None or right is not None: + for i in range(len(x)): + p.moveTo(x2[i], y1[i]) + p.lineTo(x2[i], y2[i]) + if width is not None or left is not None: + for i in range(len(x)): + p.moveTo(x1[i], y1[i]) + p.lineTo(x1[i], y2[i]) + + self.path = p + self.prepareGeometryChange() + + + def paint(self, p, *args): + if self.path is None: + self.drawPath() + pen = self.opts['pen'] + if pen is None: + pen = pg.getConfigOption('foreground') + p.setPen(pg.mkPen(pen)) + p.drawPath(self.path) + + def boundingRect(self): + if self.path is None: + return QtCore.QRectF() + return self.path.boundingRect() + + \ No newline at end of file