- Fixed FillBetweenItem to force PlotCurveItem to generate path

- Added FillBetweenItem.setCurves()
- Added FillBetweenItem example
This commit is contained in:
Luke Campagnola 2014-01-23 10:34:26 -05:00
parent 48b5e0fba3
commit 23779f004e
4 changed files with 59 additions and 10 deletions

View File

@ -23,6 +23,7 @@ pyqtgraph-0.9.9 [unreleased]
- Get, set current value
- Added Flowchart.sigChartChanged
- ImageItem.getHistogram is more clever about constructing histograms
- Added FillBetweenItem.setCurves()
Bugfixes:
- PlotCurveItem now has correct clicking behavior--clicks within a few px
@ -42,6 +43,7 @@ pyqtgraph-0.9.9 [unreleased]
- Prevent divide-by-zero in AxisItem
- Major speedup when using ScatterPlotItem in pxMode
- PlotCurveItem ignores clip-to-view when auto range is enabled
- FillBetweenItem now forces PlotCurveItem to generate path
pyqtgraph-0.9.8 2013-11-24

View File

@ -37,6 +37,7 @@ examples = OrderedDict([
('IsocurveItem', 'isocurve.py'),
('GraphItem', 'GraphItem.py'),
('ErrorBarItem', 'ErrorBarItem.py'),
('FillBetweenItem', 'FillBetweenItem.py'),
('ImageItem - video', 'ImageItem.py'),
('ImageItem - draw', 'Draw.py'),
('Region-of-Interest', 'ROIExamples.py'),

View File

@ -1,24 +1,70 @@
from ..Qt import QtGui
from .. import functions as fn
from .PlotDataItem import PlotDataItem
from .PlotCurveItem import PlotCurveItem
class FillBetweenItem(QtGui.QGraphicsPathItem):
"""
GraphicsItem filling the space between two PlotDataItems.
"""
def __init__(self, p1, p2, brush=None):
def __init__(self, curve1=None, curve2=None, brush=None):
QtGui.QGraphicsPathItem.__init__(self)
self.p1 = p1
self.p2 = p2
p1.sigPlotChanged.connect(self.updatePath)
p2.sigPlotChanged.connect(self.updatePath)
self.curves = None
if curve1 is not None and curve2 is not None:
self.setCurves(curve1, curve2)
elif curve1 is not None or curve2 is not None:
raise Exception("Must specify two curves to fill between.")
if brush is not None:
self.setBrush(fn.mkBrush(brush))
self.setZValue(min(p1.zValue(), p2.zValue())-1)
self.updatePath()
def setCurves(self, curve1, curve2):
"""Set the curves to fill between.
Arguments must be instances of PlotDataItem or PlotCurveItem."""
if self.curves is not None:
for c in self.curves:
try:
c.sigPlotChanged.disconnect(self.curveChanged)
except TypeError:
pass
curves = [curve1, curve2]
for c in curves:
if not isinstance(c, PlotDataItem) and not isinstance(c, PlotCurveItem):
raise TypeError("Curves must be PlotDataItem or PlotCurveItem.")
self.curves = curves
curve1.sigPlotChanged.connect(self.curveChanged)
curve2.sigPlotChanged.connect(self.curveChanged)
self.setZValue(min(curve1.zValue(), curve2.zValue())-1)
self.curveChanged()
def setBrush(self, *args, **kwds):
"""Change the fill brush. Acceps the same arguments as pg.mkBrush()"""
QtGui.QGraphicsPathItem.setBrush(self, fn.mkBrush(*args, **kwds))
def curveChanged(self):
self.updatePath()
def updatePath(self):
p1 = self.p1.curve.path
p2 = self.p2.curve.path
if self.curves is None:
self.setPath(QtGui.QPainterPath())
return
paths = []
for c in self.curves:
if isinstance(c, PlotDataItem):
paths.append(c.curve.getPath())
elif isinstance(c, PlotCurveItem):
paths.append(c.getPath())
path = QtGui.QPainterPath()
path.addPolygon(p1.toSubpathPolygons()[0] + p2.toReversed().toSubpathPolygons()[0])
p1 = paths[0].toSubpathPolygons()
p2 = paths[1].toReversed().toSubpathPolygons()
if len(p1) == 0 or len(p2) == 0:
self.setPath(QtGui.QPainterPath())
return
path.addPolygon(p1[0] + p2[0])
self.setPath(path)

View File

@ -15,7 +15,7 @@ class PlotDataItem(GraphicsObject):
GraphicsItem for displaying plot curves, scatter plots, or both.
While it is possible to use :class:`PlotCurveItem <pyqtgraph.PlotCurveItem>` or
:class:`ScatterPlotItem <pyqtgraph.ScatterPlotItem>` individually, this class
provides a unified interface to both. Inspances of :class:`PlotDataItem` are
provides a unified interface to both. Instances of :class:`PlotDataItem` are
usually created by plot() methods such as :func:`pyqtgraph.plot` and
:func:`PlotItem.plot() <pyqtgraph.PlotItem.plot>`.