Consolidate to simpler get is not none check.
This commit is contained in:
parent
17e90af36c
commit
18999c2ca1
@ -4,7 +4,7 @@ try:
|
|||||||
HAVE_OPENGL = True
|
HAVE_OPENGL = True
|
||||||
except:
|
except:
|
||||||
HAVE_OPENGL = False
|
HAVE_OPENGL = False
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from .GraphicsObject import GraphicsObject
|
from .GraphicsObject import GraphicsObject
|
||||||
from .. import functions as fn
|
from .. import functions as fn
|
||||||
@ -15,48 +15,48 @@ from .. import debug
|
|||||||
|
|
||||||
__all__ = ['PlotCurveItem']
|
__all__ = ['PlotCurveItem']
|
||||||
class PlotCurveItem(GraphicsObject):
|
class PlotCurveItem(GraphicsObject):
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Class representing a single plot curve. Instances of this class are created
|
Class representing a single plot curve. Instances of this class are created
|
||||||
automatically as part of PlotDataItem; these rarely need to be instantiated
|
automatically as part of PlotDataItem; these rarely need to be instantiated
|
||||||
directly.
|
directly.
|
||||||
|
|
||||||
Features:
|
Features:
|
||||||
|
|
||||||
- Fast data update
|
- Fast data update
|
||||||
- Fill under curve
|
- Fill under curve
|
||||||
- Mouse interaction
|
- Mouse interaction
|
||||||
|
|
||||||
==================== ===============================================
|
==================== ===============================================
|
||||||
**Signals:**
|
**Signals:**
|
||||||
sigPlotChanged(self) Emitted when the data being plotted has changed
|
sigPlotChanged(self) Emitted when the data being plotted has changed
|
||||||
sigClicked(self) Emitted when the curve is clicked
|
sigClicked(self) Emitted when the curve is clicked
|
||||||
==================== ===============================================
|
==================== ===============================================
|
||||||
"""
|
"""
|
||||||
|
|
||||||
sigPlotChanged = QtCore.Signal(object)
|
sigPlotChanged = QtCore.Signal(object)
|
||||||
sigClicked = QtCore.Signal(object)
|
sigClicked = QtCore.Signal(object)
|
||||||
|
|
||||||
def __init__(self, *args, **kargs):
|
def __init__(self, *args, **kargs):
|
||||||
"""
|
"""
|
||||||
Forwards all arguments to :func:`setData <pyqtgraph.PlotCurveItem.setData>`.
|
Forwards all arguments to :func:`setData <pyqtgraph.PlotCurveItem.setData>`.
|
||||||
|
|
||||||
Some extra arguments are accepted as well:
|
Some extra arguments are accepted as well:
|
||||||
|
|
||||||
============== =======================================================
|
============== =======================================================
|
||||||
**Arguments:**
|
**Arguments:**
|
||||||
parent The parent GraphicsObject (optional)
|
parent The parent GraphicsObject (optional)
|
||||||
clickable If True, the item will emit sigClicked when it is
|
clickable If True, the item will emit sigClicked when it is
|
||||||
clicked on. Defaults to False.
|
clicked on. Defaults to False.
|
||||||
============== =======================================================
|
============== =======================================================
|
||||||
"""
|
"""
|
||||||
GraphicsObject.__init__(self, kargs.get('parent', None))
|
GraphicsObject.__init__(self, kargs.get('parent', None))
|
||||||
self.clear()
|
self.clear()
|
||||||
|
|
||||||
## this is disastrous for performance.
|
## this is disastrous for performance.
|
||||||
#self.setCacheMode(QtGui.QGraphicsItem.DeviceCoordinateCache)
|
#self.setCacheMode(QtGui.QGraphicsItem.DeviceCoordinateCache)
|
||||||
|
|
||||||
self.metaData = {}
|
self.metaData = {}
|
||||||
self.opts = {
|
self.opts = {
|
||||||
'shadowPen': None,
|
'shadowPen': None,
|
||||||
@ -72,19 +72,19 @@ class PlotCurveItem(GraphicsObject):
|
|||||||
|
|
||||||
self.setClickable(kargs.get('clickable', False))
|
self.setClickable(kargs.get('clickable', False))
|
||||||
self.setData(*args, **kargs)
|
self.setData(*args, **kargs)
|
||||||
|
|
||||||
def implements(self, interface=None):
|
def implements(self, interface=None):
|
||||||
ints = ['plotData']
|
ints = ['plotData']
|
||||||
if interface is None:
|
if interface is None:
|
||||||
return ints
|
return ints
|
||||||
return interface in ints
|
return interface in ints
|
||||||
|
|
||||||
def name(self):
|
def name(self):
|
||||||
return self.opts.get('name', None)
|
return self.opts.get('name', None)
|
||||||
|
|
||||||
def setClickable(self, s, width=None):
|
def setClickable(self, s, width=None):
|
||||||
"""Sets whether the item responds to mouse clicks.
|
"""Sets whether the item responds to mouse clicks.
|
||||||
|
|
||||||
The *width* argument specifies the width in pixels orthogonal to the
|
The *width* argument specifies the width in pixels orthogonal to the
|
||||||
curve that will respond to a mouse click.
|
curve that will respond to a mouse click.
|
||||||
"""
|
"""
|
||||||
@ -92,41 +92,41 @@ class PlotCurveItem(GraphicsObject):
|
|||||||
if width is not None:
|
if width is not None:
|
||||||
self.opts['mouseWidth'] = width
|
self.opts['mouseWidth'] = width
|
||||||
self._mouseShape = None
|
self._mouseShape = None
|
||||||
self._boundingRect = None
|
self._boundingRect = None
|
||||||
|
|
||||||
def setCompositionMode(self, mode):
|
def setCompositionMode(self, mode):
|
||||||
"""Change the composition mode of the item (see QPainter::CompositionMode
|
"""Change the composition mode of the item (see QPainter::CompositionMode
|
||||||
in the Qt documentation). This is useful when overlaying multiple items.
|
in the Qt documentation). This is useful when overlaying multiple items.
|
||||||
|
|
||||||
============================================ ============================================================
|
============================================ ============================================================
|
||||||
**Most common arguments:**
|
**Most common arguments:**
|
||||||
QtGui.QPainter.CompositionMode_SourceOver Default; image replaces the background if it
|
QtGui.QPainter.CompositionMode_SourceOver Default; image replaces the background if it
|
||||||
is opaque. Otherwise, it uses the alpha channel to blend
|
is opaque. Otherwise, it uses the alpha channel to blend
|
||||||
the image with the background.
|
the image with the background.
|
||||||
QtGui.QPainter.CompositionMode_Overlay The image color is mixed with the background color to
|
QtGui.QPainter.CompositionMode_Overlay The image color is mixed with the background color to
|
||||||
reflect the lightness or darkness of the background.
|
reflect the lightness or darkness of the background.
|
||||||
QtGui.QPainter.CompositionMode_Plus Both the alpha and color of the image and background pixels
|
QtGui.QPainter.CompositionMode_Plus Both the alpha and color of the image and background pixels
|
||||||
are added together.
|
are added together.
|
||||||
QtGui.QPainter.CompositionMode_Multiply The output is the image color multiplied by the background.
|
QtGui.QPainter.CompositionMode_Multiply The output is the image color multiplied by the background.
|
||||||
============================================ ============================================================
|
============================================ ============================================================
|
||||||
"""
|
"""
|
||||||
self.opts['compositionMode'] = mode
|
self.opts['compositionMode'] = mode
|
||||||
self.update()
|
self.update()
|
||||||
|
|
||||||
def getData(self):
|
def getData(self):
|
||||||
return self.xData, self.yData
|
return self.xData, self.yData
|
||||||
|
|
||||||
def dataBounds(self, ax, frac=1.0, orthoRange=None):
|
def dataBounds(self, ax, frac=1.0, orthoRange=None):
|
||||||
## Need this to run as fast as possible.
|
## Need this to run as fast as possible.
|
||||||
## check cache first:
|
## check cache first:
|
||||||
cache = self._boundsCache[ax]
|
cache = self._boundsCache[ax]
|
||||||
if cache is not None and cache[0] == (frac, orthoRange):
|
if cache is not None and cache[0] == (frac, orthoRange):
|
||||||
return cache[1]
|
return cache[1]
|
||||||
|
|
||||||
(x, y) = self.getData()
|
(x, y) = self.getData()
|
||||||
if x is None or len(x) == 0:
|
if x is None or len(x) == 0:
|
||||||
return (None, None)
|
return (None, None)
|
||||||
|
|
||||||
if ax == 0:
|
if ax == 0:
|
||||||
d = x
|
d = x
|
||||||
d2 = y
|
d2 = y
|
||||||
@ -139,7 +139,7 @@ class PlotCurveItem(GraphicsObject):
|
|||||||
mask = (d2 >= orthoRange[0]) * (d2 <= orthoRange[1])
|
mask = (d2 >= orthoRange[0]) * (d2 <= orthoRange[1])
|
||||||
d = d[mask]
|
d = d[mask]
|
||||||
#d2 = d2[mask]
|
#d2 = d2[mask]
|
||||||
|
|
||||||
if len(d) == 0:
|
if len(d) == 0:
|
||||||
return (None, None)
|
return (None, None)
|
||||||
|
|
||||||
@ -154,7 +154,7 @@ class PlotCurveItem(GraphicsObject):
|
|||||||
if len(d) == 0:
|
if len(d) == 0:
|
||||||
return (None, None)
|
return (None, None)
|
||||||
b = (d.min(), d.max())
|
b = (d.min(), d.max())
|
||||||
|
|
||||||
elif frac <= 0.0:
|
elif frac <= 0.0:
|
||||||
raise Exception("Value for parameter 'frac' must be > 0. (got %s)" % str(frac))
|
raise Exception("Value for parameter 'frac' must be > 0. (got %s)" % str(frac))
|
||||||
else:
|
else:
|
||||||
@ -166,7 +166,7 @@ class PlotCurveItem(GraphicsObject):
|
|||||||
## adjust for fill level
|
## adjust for fill level
|
||||||
if ax == 1 and self.opts['fillLevel'] is not None:
|
if ax == 1 and self.opts['fillLevel'] is not None:
|
||||||
b = (min(b[0], self.opts['fillLevel']), max(b[1], self.opts['fillLevel']))
|
b = (min(b[0], self.opts['fillLevel']), max(b[1], self.opts['fillLevel']))
|
||||||
|
|
||||||
## Add pen width only if it is non-cosmetic.
|
## Add pen width only if it is non-cosmetic.
|
||||||
pen = self.opts['pen']
|
pen = self.opts['pen']
|
||||||
spen = self.opts['shadowPen']
|
spen = self.opts['shadowPen']
|
||||||
@ -174,10 +174,10 @@ class PlotCurveItem(GraphicsObject):
|
|||||||
b = (b[0] - pen.widthF()*0.7072, b[1] + pen.widthF()*0.7072)
|
b = (b[0] - pen.widthF()*0.7072, b[1] + pen.widthF()*0.7072)
|
||||||
if spen is not None and not spen.isCosmetic() and spen.style() != QtCore.Qt.NoPen:
|
if spen is not None and not spen.isCosmetic() and spen.style() != QtCore.Qt.NoPen:
|
||||||
b = (b[0] - spen.widthF()*0.7072, b[1] + spen.widthF()*0.7072)
|
b = (b[0] - spen.widthF()*0.7072, b[1] + spen.widthF()*0.7072)
|
||||||
|
|
||||||
self._boundsCache[ax] = [(frac, orthoRange), b]
|
self._boundsCache[ax] = [(frac, orthoRange), b]
|
||||||
return b
|
return b
|
||||||
|
|
||||||
def pixelPadding(self):
|
def pixelPadding(self):
|
||||||
pen = self.opts['pen']
|
pen = self.opts['pen']
|
||||||
spen = self.opts['shadowPen']
|
spen = self.opts['shadowPen']
|
||||||
@ -196,11 +196,11 @@ class PlotCurveItem(GraphicsObject):
|
|||||||
(ymn, ymx) = self.dataBounds(ax=1)
|
(ymn, ymx) = self.dataBounds(ax=1)
|
||||||
if xmn is None or ymn is None:
|
if xmn is None or ymn is None:
|
||||||
return QtCore.QRectF()
|
return QtCore.QRectF()
|
||||||
|
|
||||||
px = py = 0.0
|
px = py = 0.0
|
||||||
pxPad = self.pixelPadding()
|
pxPad = self.pixelPadding()
|
||||||
if pxPad > 0:
|
if pxPad > 0:
|
||||||
# determine length of pixel in local x, y directions
|
# determine length of pixel in local x, y directions
|
||||||
px, py = self.pixelVectors()
|
px, py = self.pixelVectors()
|
||||||
try:
|
try:
|
||||||
px = 0 if px is None else px.length()
|
px = 0 if px is None else px.length()
|
||||||
@ -210,68 +210,68 @@ class PlotCurveItem(GraphicsObject):
|
|||||||
py = 0 if py is None else py.length()
|
py = 0 if py is None else py.length()
|
||||||
except OverflowError:
|
except OverflowError:
|
||||||
py = 0
|
py = 0
|
||||||
|
|
||||||
# return bounds expanded by pixel size
|
# return bounds expanded by pixel size
|
||||||
px *= pxPad
|
px *= pxPad
|
||||||
py *= pxPad
|
py *= pxPad
|
||||||
#px += self._maxSpotWidth * 0.5
|
#px += self._maxSpotWidth * 0.5
|
||||||
#py += self._maxSpotWidth * 0.5
|
#py += self._maxSpotWidth * 0.5
|
||||||
self._boundingRect = QtCore.QRectF(xmn-px, ymn-py, (2*px)+xmx-xmn, (2*py)+ymx-ymn)
|
self._boundingRect = QtCore.QRectF(xmn-px, ymn-py, (2*px)+xmx-xmn, (2*py)+ymx-ymn)
|
||||||
|
|
||||||
return self._boundingRect
|
return self._boundingRect
|
||||||
|
|
||||||
def viewTransformChanged(self):
|
def viewTransformChanged(self):
|
||||||
self.invalidateBounds()
|
self.invalidateBounds()
|
||||||
self.prepareGeometryChange()
|
self.prepareGeometryChange()
|
||||||
|
|
||||||
#def boundingRect(self):
|
#def boundingRect(self):
|
||||||
#if self._boundingRect is None:
|
#if self._boundingRect is None:
|
||||||
#(x, y) = self.getData()
|
#(x, y) = self.getData()
|
||||||
#if x is None or y is None or len(x) == 0 or len(y) == 0:
|
#if x is None or y is None or len(x) == 0 or len(y) == 0:
|
||||||
#return QtCore.QRectF()
|
#return QtCore.QRectF()
|
||||||
|
|
||||||
|
|
||||||
#if self.opts['shadowPen'] is not None:
|
#if self.opts['shadowPen'] is not None:
|
||||||
#lineWidth = (max(self.opts['pen'].width(), self.opts['shadowPen'].width()) + 1)
|
#lineWidth = (max(self.opts['pen'].width(), self.opts['shadowPen'].width()) + 1)
|
||||||
#else:
|
#else:
|
||||||
#lineWidth = (self.opts['pen'].width()+1)
|
#lineWidth = (self.opts['pen'].width()+1)
|
||||||
|
|
||||||
|
|
||||||
#pixels = self.pixelVectors()
|
#pixels = self.pixelVectors()
|
||||||
#if pixels == (None, None):
|
#if pixels == (None, None):
|
||||||
#pixels = [Point(0,0), Point(0,0)]
|
#pixels = [Point(0,0), Point(0,0)]
|
||||||
|
|
||||||
#xmin = x.min()
|
#xmin = x.min()
|
||||||
#xmax = x.max()
|
#xmax = x.max()
|
||||||
#ymin = y.min()
|
#ymin = y.min()
|
||||||
#ymax = y.max()
|
#ymax = y.max()
|
||||||
|
|
||||||
#if self.opts['fillLevel'] is not None:
|
#if self.opts['fillLevel'] is not None:
|
||||||
#ymin = min(ymin, self.opts['fillLevel'])
|
#ymin = min(ymin, self.opts['fillLevel'])
|
||||||
#ymax = max(ymax, self.opts['fillLevel'])
|
#ymax = max(ymax, self.opts['fillLevel'])
|
||||||
|
|
||||||
#xmin -= pixels[0].x() * lineWidth
|
#xmin -= pixels[0].x() * lineWidth
|
||||||
#xmax += pixels[0].x() * lineWidth
|
#xmax += pixels[0].x() * lineWidth
|
||||||
#ymin -= abs(pixels[1].y()) * lineWidth
|
#ymin -= abs(pixels[1].y()) * lineWidth
|
||||||
#ymax += abs(pixels[1].y()) * lineWidth
|
#ymax += abs(pixels[1].y()) * lineWidth
|
||||||
|
|
||||||
#self._boundingRect = QtCore.QRectF(xmin, ymin, xmax-xmin, ymax-ymin)
|
#self._boundingRect = QtCore.QRectF(xmin, ymin, xmax-xmin, ymax-ymin)
|
||||||
#return self._boundingRect
|
#return self._boundingRect
|
||||||
|
|
||||||
|
|
||||||
def invalidateBounds(self):
|
def invalidateBounds(self):
|
||||||
self._boundingRect = None
|
self._boundingRect = None
|
||||||
self._boundsCache = [None, None]
|
self._boundsCache = [None, None]
|
||||||
|
|
||||||
def setPen(self, *args, **kargs):
|
def setPen(self, *args, **kargs):
|
||||||
"""Set the pen used to draw the curve."""
|
"""Set the pen used to draw the curve."""
|
||||||
self.opts['pen'] = fn.mkPen(*args, **kargs)
|
self.opts['pen'] = fn.mkPen(*args, **kargs)
|
||||||
self.invalidateBounds()
|
self.invalidateBounds()
|
||||||
self.update()
|
self.update()
|
||||||
|
|
||||||
def setShadowPen(self, *args, **kargs):
|
def setShadowPen(self, *args, **kargs):
|
||||||
"""Set the shadow pen used to draw behind tyhe primary pen.
|
"""Set the shadow pen used to draw behind tyhe primary pen.
|
||||||
This pen must have a larger width than the primary
|
This pen must have a larger width than the primary
|
||||||
pen to be visible.
|
pen to be visible.
|
||||||
"""
|
"""
|
||||||
self.opts['shadowPen'] = fn.mkPen(*args, **kargs)
|
self.opts['shadowPen'] = fn.mkPen(*args, **kargs)
|
||||||
@ -283,7 +283,7 @@ class PlotCurveItem(GraphicsObject):
|
|||||||
self.opts['brush'] = fn.mkBrush(*args, **kargs)
|
self.opts['brush'] = fn.mkBrush(*args, **kargs)
|
||||||
self.invalidateBounds()
|
self.invalidateBounds()
|
||||||
self.update()
|
self.update()
|
||||||
|
|
||||||
def setFillLevel(self, level):
|
def setFillLevel(self, level):
|
||||||
"""Set the level filled to when filling under the curve"""
|
"""Set the level filled to when filling under the curve"""
|
||||||
self.opts['fillLevel'] = level
|
self.opts['fillLevel'] = level
|
||||||
@ -295,11 +295,11 @@ class PlotCurveItem(GraphicsObject):
|
|||||||
"""
|
"""
|
||||||
=============== ========================================================
|
=============== ========================================================
|
||||||
**Arguments:**
|
**Arguments:**
|
||||||
x, y (numpy arrays) Data to show
|
x, y (numpy arrays) Data to show
|
||||||
pen Pen to use when drawing. Any single argument accepted by
|
pen Pen to use when drawing. Any single argument accepted by
|
||||||
:func:`mkPen <pyqtgraph.mkPen>` is allowed.
|
:func:`mkPen <pyqtgraph.mkPen>` is allowed.
|
||||||
shadowPen Pen for drawing behind the primary pen. Usually this
|
shadowPen Pen for drawing behind the primary pen. Usually this
|
||||||
is used to emphasize the curve by providing a
|
is used to emphasize the curve by providing a
|
||||||
high-contrast border. Any single argument accepted by
|
high-contrast border. Any single argument accepted by
|
||||||
:func:`mkPen <pyqtgraph.mkPen>` is allowed.
|
:func:`mkPen <pyqtgraph.mkPen>` is allowed.
|
||||||
fillLevel (float or None) Fill the area 'under' the curve to
|
fillLevel (float or None) Fill the area 'under' the curve to
|
||||||
@ -317,18 +317,18 @@ class PlotCurveItem(GraphicsObject):
|
|||||||
to be drawn. "finite" causes segments to be omitted if
|
to be drawn. "finite" causes segments to be omitted if
|
||||||
they are attached to nan or inf values. For any other
|
they are attached to nan or inf values. For any other
|
||||||
connectivity, specify an array of boolean values.
|
connectivity, specify an array of boolean values.
|
||||||
compositionMode See :func:`setCompositionMode
|
compositionMode See :func:`setCompositionMode
|
||||||
<pyqtgraph.PlotCurveItem.setCompositionMode>`.
|
<pyqtgraph.PlotCurveItem.setCompositionMode>`.
|
||||||
=============== ========================================================
|
=============== ========================================================
|
||||||
|
|
||||||
If non-keyword arguments are used, they will be interpreted as
|
If non-keyword arguments are used, they will be interpreted as
|
||||||
setData(y) for a single argument and setData(x, y) for two
|
setData(y) for a single argument and setData(x, y) for two
|
||||||
arguments.
|
arguments.
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
self.updateData(*args, **kargs)
|
self.updateData(*args, **kargs)
|
||||||
|
|
||||||
def updateData(self, *args, **kargs):
|
def updateData(self, *args, **kargs):
|
||||||
profiler = debug.Profiler()
|
profiler = debug.Profiler()
|
||||||
|
|
||||||
@ -340,12 +340,12 @@ class PlotCurveItem(GraphicsObject):
|
|||||||
elif len(args) == 2:
|
elif len(args) == 2:
|
||||||
kargs['x'] = args[0]
|
kargs['x'] = args[0]
|
||||||
kargs['y'] = args[1]
|
kargs['y'] = args[1]
|
||||||
|
|
||||||
if 'y' not in kargs or kargs['y'] is None:
|
if 'y' not in kargs or kargs['y'] is None:
|
||||||
kargs['y'] = np.array([])
|
kargs['y'] = np.array([])
|
||||||
if 'x' not in kargs or kargs['x'] is None:
|
if 'x' not in kargs or kargs['x'] is None:
|
||||||
kargs['x'] = np.arange(len(kargs['y']))
|
kargs['x'] = np.arange(len(kargs['y']))
|
||||||
|
|
||||||
for k in ['x', 'y']:
|
for k in ['x', 'y']:
|
||||||
data = kargs[k]
|
data = kargs[k]
|
||||||
if isinstance(data, list):
|
if isinstance(data, list):
|
||||||
@ -355,9 +355,9 @@ class PlotCurveItem(GraphicsObject):
|
|||||||
raise Exception("Plot data must be 1D ndarray.")
|
raise Exception("Plot data must be 1D ndarray.")
|
||||||
if 'complex' in str(data.dtype):
|
if 'complex' in str(data.dtype):
|
||||||
raise Exception("Can not plot complex data types.")
|
raise Exception("Can not plot complex data types.")
|
||||||
|
|
||||||
profiler("data checks")
|
profiler("data checks")
|
||||||
|
|
||||||
#self.setCacheMode(QtGui.QGraphicsItem.NoCache) ## Disabling and re-enabling the cache works around a bug in Qt 4.6 causing the cached results to display incorrectly
|
#self.setCacheMode(QtGui.QGraphicsItem.NoCache) ## Disabling and re-enabling the cache works around a bug in Qt 4.6 causing the cached results to display incorrectly
|
||||||
## Test this bug with test_PlotWidget and zoom in on the animated plot
|
## Test this bug with test_PlotWidget and zoom in on the animated plot
|
||||||
self.invalidateBounds()
|
self.invalidateBounds()
|
||||||
@ -365,46 +365,46 @@ class PlotCurveItem(GraphicsObject):
|
|||||||
self.informViewBoundsChanged()
|
self.informViewBoundsChanged()
|
||||||
self.yData = kargs['y'].view(np.ndarray)
|
self.yData = kargs['y'].view(np.ndarray)
|
||||||
self.xData = kargs['x'].view(np.ndarray)
|
self.xData = kargs['x'].view(np.ndarray)
|
||||||
|
|
||||||
profiler('copy')
|
profiler('copy')
|
||||||
|
|
||||||
if 'stepMode' in kargs:
|
if 'stepMode' in kargs:
|
||||||
self.opts['stepMode'] = kargs['stepMode']
|
self.opts['stepMode'] = kargs['stepMode']
|
||||||
|
|
||||||
if self.opts['stepMode'] is True:
|
if self.opts['stepMode'] is True:
|
||||||
if len(self.xData) != len(self.yData)+1: ## allow difference of 1 for step mode plots
|
if len(self.xData) != len(self.yData)+1: ## allow difference of 1 for step mode plots
|
||||||
raise Exception("len(X) must be len(Y)+1 since stepMode=True (got %s and %s)" % (self.xData.shape, self.yData.shape))
|
raise Exception("len(X) must be len(Y)+1 since stepMode=True (got %s and %s)" % (self.xData.shape, self.yData.shape))
|
||||||
else:
|
else:
|
||||||
if self.xData.shape != self.yData.shape: ## allow difference of 1 for step mode plots
|
if self.xData.shape != self.yData.shape: ## allow difference of 1 for step mode plots
|
||||||
raise Exception("X and Y arrays must be the same shape--got %s and %s." % (self.xData.shape, self.yData.shape))
|
raise Exception("X and Y arrays must be the same shape--got %s and %s." % (self.xData.shape, self.yData.shape))
|
||||||
|
|
||||||
self.path = None
|
self.path = None
|
||||||
self.fillPath = None
|
self.fillPath = None
|
||||||
self._mouseShape = None
|
self._mouseShape = None
|
||||||
#self.xDisp = self.yDisp = None
|
#self.xDisp = self.yDisp = None
|
||||||
|
|
||||||
if 'name' in kargs:
|
if kargs.get("name") is not None:
|
||||||
self.opts['name'] = kargs['name']
|
self.opts['name'] = kargs['name']
|
||||||
if 'connect' in kargs:
|
if kargs.get("connect") is not None:
|
||||||
self.opts['connect'] = kargs['connect']
|
self.opts['connect'] = kargs['connect']
|
||||||
if 'pen' in kargs:
|
if kargs.get("pen") is not None:
|
||||||
self.setPen(kargs['pen'])
|
self.setPen(kargs['pen'])
|
||||||
if 'shadowPen' in kargs and kargs['shadowPen'] is not None:
|
if kargs.get("shadowPen") is not None:
|
||||||
self.setShadowPen(kargs['shadowPen'])
|
self.setShadowPen(kargs['shadowPen'])
|
||||||
if 'fillLevel' in kargs and kargs['fillLevel'] is not None:
|
if kargs.get("fillLevel") is not None:
|
||||||
self.setFillLevel(kargs['fillLevel'])
|
self.setFillLevel(kargs['fillLevel'])
|
||||||
if 'brush' in kargs and kargs['brush'] is not None:
|
if kargs.get("brush") is not None:
|
||||||
self.setBrush(kargs['brush'])
|
self.setBrush(kargs['brush'])
|
||||||
if 'antialias' in kargs:
|
if kargs.get("antialias") is not None:
|
||||||
self.opts['antialias'] = kargs['antialias']
|
self.opts['antialias'] = kargs['antialias']
|
||||||
|
|
||||||
|
|
||||||
profiler('set')
|
profiler('set')
|
||||||
self.update()
|
self.update()
|
||||||
profiler('update')
|
profiler('update')
|
||||||
self.sigPlotChanged.emit(self)
|
self.sigPlotChanged.emit(self)
|
||||||
profiler('emit')
|
profiler('emit')
|
||||||
|
|
||||||
def generatePath(self, x, y):
|
def generatePath(self, x, y):
|
||||||
if self.opts['stepMode']:
|
if self.opts['stepMode']:
|
||||||
## each value in the x/y arrays generates 2 points.
|
## each value in the x/y arrays generates 2 points.
|
||||||
@ -423,9 +423,9 @@ class PlotCurveItem(GraphicsObject):
|
|||||||
y = y2.reshape(y2.size)[1:-1]
|
y = y2.reshape(y2.size)[1:-1]
|
||||||
y[0] = self.opts['fillLevel']
|
y[0] = self.opts['fillLevel']
|
||||||
y[-1] = self.opts['fillLevel']
|
y[-1] = self.opts['fillLevel']
|
||||||
|
|
||||||
path = fn.arrayToQPath(x, y, connect=self.opts['connect'])
|
path = fn.arrayToQPath(x, y, connect=self.opts['connect'])
|
||||||
|
|
||||||
return path
|
return path
|
||||||
|
|
||||||
|
|
||||||
@ -438,7 +438,7 @@ class PlotCurveItem(GraphicsObject):
|
|||||||
self.path = self.generatePath(*self.getData())
|
self.path = self.generatePath(*self.getData())
|
||||||
self.fillPath = None
|
self.fillPath = None
|
||||||
self._mouseShape = None
|
self._mouseShape = None
|
||||||
|
|
||||||
return self.path
|
return self.path
|
||||||
|
|
||||||
@debug.warnOnException ## raising an exception here causes crash
|
@debug.warnOnException ## raising an exception here causes crash
|
||||||
@ -446,27 +446,27 @@ class PlotCurveItem(GraphicsObject):
|
|||||||
profiler = debug.Profiler()
|
profiler = debug.Profiler()
|
||||||
if self.xData is None or len(self.xData) == 0:
|
if self.xData is None or len(self.xData) == 0:
|
||||||
return
|
return
|
||||||
|
|
||||||
if HAVE_OPENGL and getConfigOption('enableExperimental') and isinstance(widget, QtOpenGL.QGLWidget):
|
if HAVE_OPENGL and getConfigOption('enableExperimental') and isinstance(widget, QtOpenGL.QGLWidget):
|
||||||
self.paintGL(p, opt, widget)
|
self.paintGL(p, opt, widget)
|
||||||
return
|
return
|
||||||
|
|
||||||
x = None
|
x = None
|
||||||
y = None
|
y = None
|
||||||
path = self.getPath()
|
path = self.getPath()
|
||||||
profiler('generate path')
|
profiler('generate path')
|
||||||
|
|
||||||
if self._exportOpts is not False:
|
if self._exportOpts is not False:
|
||||||
aa = self._exportOpts.get('antialias', True)
|
aa = self._exportOpts.get('antialias', True)
|
||||||
else:
|
else:
|
||||||
aa = self.opts['antialias']
|
aa = self.opts['antialias']
|
||||||
|
|
||||||
p.setRenderHint(p.Antialiasing, aa)
|
p.setRenderHint(p.Antialiasing, aa)
|
||||||
|
|
||||||
cmode = self.opts['compositionMode']
|
cmode = self.opts['compositionMode']
|
||||||
if cmode is not None:
|
if cmode is not None:
|
||||||
p.setCompositionMode(cmode)
|
p.setCompositionMode(cmode)
|
||||||
|
|
||||||
if self.opts['brush'] is not None and self.opts['fillLevel'] is not None:
|
if self.opts['brush'] is not None and self.opts['fillLevel'] is not None:
|
||||||
if self.fillPath is None:
|
if self.fillPath is None:
|
||||||
if x is None:
|
if x is None:
|
||||||
@ -477,14 +477,13 @@ class PlotCurveItem(GraphicsObject):
|
|||||||
p2.lineTo(x[0], y[0])
|
p2.lineTo(x[0], y[0])
|
||||||
p2.closeSubpath()
|
p2.closeSubpath()
|
||||||
self.fillPath = p2
|
self.fillPath = p2
|
||||||
|
|
||||||
profiler('generate fill path')
|
profiler('generate fill path')
|
||||||
p.fillPath(self.fillPath, self.opts['brush'])
|
p.fillPath(self.fillPath, self.opts['brush'])
|
||||||
profiler('draw fill path')
|
profiler('draw fill path')
|
||||||
|
|
||||||
sp = self.opts['shadowPen']
|
cp = fn.mkPen(self.opts['pen'])
|
||||||
cp = self.opts['pen']
|
|
||||||
|
|
||||||
## Copy pens and apply alpha adjustment
|
## Copy pens and apply alpha adjustment
|
||||||
#sp = QtGui.QPen(self.opts['shadowPen'])
|
#sp = QtGui.QPen(self.opts['shadowPen'])
|
||||||
#cp = QtGui.QPen(self.opts['pen'])
|
#cp = QtGui.QPen(self.opts['pen'])
|
||||||
@ -495,7 +494,7 @@ class PlotCurveItem(GraphicsObject):
|
|||||||
#c.setAlpha(c.alpha() * self.opts['alphaHint'])
|
#c.setAlpha(c.alpha() * self.opts['alphaHint'])
|
||||||
#pen.setColor(c)
|
#pen.setColor(c)
|
||||||
##pen.setCosmetic(True)
|
##pen.setCosmetic(True)
|
||||||
|
|
||||||
if sp is not None and sp.style() != QtCore.Qt.NoPen:
|
if sp is not None and sp.style() != QtCore.Qt.NoPen:
|
||||||
p.setPen(sp)
|
p.setPen(sp)
|
||||||
p.drawPath(path)
|
p.drawPath(path)
|
||||||
@ -509,25 +508,25 @@ class PlotCurveItem(GraphicsObject):
|
|||||||
#print "Render hints:", int(p.renderHints())
|
#print "Render hints:", int(p.renderHints())
|
||||||
#p.setPen(QtGui.QPen(QtGui.QColor(255,0,0)))
|
#p.setPen(QtGui.QPen(QtGui.QColor(255,0,0)))
|
||||||
#p.drawRect(self.boundingRect())
|
#p.drawRect(self.boundingRect())
|
||||||
|
|
||||||
def paintGL(self, p, opt, widget):
|
def paintGL(self, p, opt, widget):
|
||||||
p.beginNativePainting()
|
p.beginNativePainting()
|
||||||
import OpenGL.GL as gl
|
import OpenGL.GL as gl
|
||||||
|
|
||||||
## set clipping viewport
|
## set clipping viewport
|
||||||
view = self.getViewBox()
|
view = self.getViewBox()
|
||||||
if view is not None:
|
if view is not None:
|
||||||
rect = view.mapRectToItem(self, view.boundingRect())
|
rect = view.mapRectToItem(self, view.boundingRect())
|
||||||
#gl.glViewport(int(rect.x()), int(rect.y()), int(rect.width()), int(rect.height()))
|
#gl.glViewport(int(rect.x()), int(rect.y()), int(rect.width()), int(rect.height()))
|
||||||
|
|
||||||
#gl.glTranslate(-rect.x(), -rect.y(), 0)
|
#gl.glTranslate(-rect.x(), -rect.y(), 0)
|
||||||
|
|
||||||
gl.glEnable(gl.GL_STENCIL_TEST)
|
gl.glEnable(gl.GL_STENCIL_TEST)
|
||||||
gl.glColorMask(gl.GL_FALSE, gl.GL_FALSE, gl.GL_FALSE, gl.GL_FALSE) # disable drawing to frame buffer
|
gl.glColorMask(gl.GL_FALSE, gl.GL_FALSE, gl.GL_FALSE, gl.GL_FALSE) # disable drawing to frame buffer
|
||||||
gl.glDepthMask(gl.GL_FALSE) # disable drawing to depth buffer
|
gl.glDepthMask(gl.GL_FALSE) # disable drawing to depth buffer
|
||||||
gl.glStencilFunc(gl.GL_NEVER, 1, 0xFF)
|
gl.glStencilFunc(gl.GL_NEVER, 1, 0xFF)
|
||||||
gl.glStencilOp(gl.GL_REPLACE, gl.GL_KEEP, gl.GL_KEEP)
|
gl.glStencilOp(gl.GL_REPLACE, gl.GL_KEEP, gl.GL_KEEP)
|
||||||
|
|
||||||
## draw stencil pattern
|
## draw stencil pattern
|
||||||
gl.glStencilMask(0xFF)
|
gl.glStencilMask(0xFF)
|
||||||
gl.glClear(gl.GL_STENCIL_BUFFER_BIT)
|
gl.glClear(gl.GL_STENCIL_BUFFER_BIT)
|
||||||
@ -539,12 +538,12 @@ class PlotCurveItem(GraphicsObject):
|
|||||||
gl.glVertex2f(rect.x()+rect.width(), rect.y())
|
gl.glVertex2f(rect.x()+rect.width(), rect.y())
|
||||||
gl.glVertex2f(rect.x(), rect.y()+rect.height())
|
gl.glVertex2f(rect.x(), rect.y()+rect.height())
|
||||||
gl.glEnd()
|
gl.glEnd()
|
||||||
|
|
||||||
gl.glColorMask(gl.GL_TRUE, gl.GL_TRUE, gl.GL_TRUE, gl.GL_TRUE)
|
gl.glColorMask(gl.GL_TRUE, gl.GL_TRUE, gl.GL_TRUE, gl.GL_TRUE)
|
||||||
gl.glDepthMask(gl.GL_TRUE)
|
gl.glDepthMask(gl.GL_TRUE)
|
||||||
gl.glStencilMask(0x00)
|
gl.glStencilMask(0x00)
|
||||||
gl.glStencilFunc(gl.GL_EQUAL, 1, 0xFF)
|
gl.glStencilFunc(gl.GL_EQUAL, 1, 0xFF)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
x, y = self.getData()
|
x, y = self.getData()
|
||||||
pos = np.empty((len(x), 2))
|
pos = np.empty((len(x), 2))
|
||||||
@ -569,7 +568,7 @@ class PlotCurveItem(GraphicsObject):
|
|||||||
gl.glDisableClientState(gl.GL_VERTEX_ARRAY)
|
gl.glDisableClientState(gl.GL_VERTEX_ARRAY)
|
||||||
finally:
|
finally:
|
||||||
p.endNativePainting()
|
p.endNativePainting()
|
||||||
|
|
||||||
def clear(self):
|
def clear(self):
|
||||||
self.xData = None ## raw values
|
self.xData = None ## raw values
|
||||||
self.yData = None
|
self.yData = None
|
||||||
@ -585,7 +584,7 @@ class PlotCurveItem(GraphicsObject):
|
|||||||
def mouseShape(self):
|
def mouseShape(self):
|
||||||
"""
|
"""
|
||||||
Return a QPainterPath representing the clickable shape of the curve
|
Return a QPainterPath representing the clickable shape of the curve
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if self._mouseShape is None:
|
if self._mouseShape is None:
|
||||||
view = self.getViewBox()
|
view = self.getViewBox()
|
||||||
@ -598,14 +597,14 @@ class PlotCurveItem(GraphicsObject):
|
|||||||
mousePath = stroker.createStroke(path)
|
mousePath = stroker.createStroke(path)
|
||||||
self._mouseShape = self.mapFromItem(view, mousePath)
|
self._mouseShape = self.mapFromItem(view, mousePath)
|
||||||
return self._mouseShape
|
return self._mouseShape
|
||||||
|
|
||||||
def mouseClickEvent(self, ev):
|
def mouseClickEvent(self, ev):
|
||||||
if not self.clickable or ev.button() != QtCore.Qt.LeftButton:
|
if not self.clickable or ev.button() != QtCore.Qt.LeftButton:
|
||||||
return
|
return
|
||||||
if self.mouseShape().contains(ev.pos()):
|
if self.mouseShape().contains(ev.pos()):
|
||||||
ev.accept()
|
ev.accept()
|
||||||
self.sigClicked.emit(self)
|
self.sigClicked.emit(self)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class ROIPlotItem(PlotCurveItem):
|
class ROIPlotItem(PlotCurveItem):
|
||||||
@ -620,7 +619,7 @@ class ROIPlotItem(PlotCurveItem):
|
|||||||
#roi.connect(roi, QtCore.SIGNAL('regionChanged'), self.roiChangedEvent)
|
#roi.connect(roi, QtCore.SIGNAL('regionChanged'), self.roiChangedEvent)
|
||||||
roi.sigRegionChanged.connect(self.roiChangedEvent)
|
roi.sigRegionChanged.connect(self.roiChangedEvent)
|
||||||
#self.roiChangedEvent()
|
#self.roiChangedEvent()
|
||||||
|
|
||||||
def getRoiData(self):
|
def getRoiData(self):
|
||||||
d = self.roi.getArrayRegion(self.roiData, self.roiImg, axes=self.axes)
|
d = self.roi.getArrayRegion(self.roiData, self.roiImg, axes=self.axes)
|
||||||
if d is None:
|
if d is None:
|
||||||
@ -628,7 +627,7 @@ class ROIPlotItem(PlotCurveItem):
|
|||||||
while d.ndim > 1:
|
while d.ndim > 1:
|
||||||
d = d.mean(axis=1)
|
d = d.mean(axis=1)
|
||||||
return d
|
return d
|
||||||
|
|
||||||
def roiChangedEvent(self):
|
def roiChangedEvent(self):
|
||||||
d = self.getRoiData()
|
d = self.getRoiData()
|
||||||
self.updateData(d, self.xVals)
|
self.updateData(d, self.xVals)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user