diff --git a/pyqtgraph/functions.py b/pyqtgraph/functions.py index db77ea51..8a250df3 100644 --- a/pyqtgraph/functions.py +++ b/pyqtgraph/functions.py @@ -1678,7 +1678,7 @@ def downsample(data, n, axis=0, xvals='subsample'): return MetaArray(d2, info=info) -def arrayToQPath(x, y, connect='all'): +def arrayToQPath(x, y, connect='all', finiteCheck=True): """Convert an array of x,y coordinats to QPainterPath as efficiently as possible. The *connect* argument may be 'all', indicating that each point should be connected to the next; 'pairs', indicating that each pair of points @@ -1735,7 +1735,7 @@ def arrayToQPath(x, y, connect='all'): # Qt version 5.12.3; these must now be manually cleaned out. isfinite = None qtver = [int(x) for x in QtVersion.split('.')] - if qtver >= [5, 12, 3]: + if qtver >= [5, 12, 3] and finiteCheck: isfinite = np.isfinite(x) & np.isfinite(y) if not np.all(isfinite): # credit: Divakar https://stackoverflow.com/a/41191127/643629 diff --git a/pyqtgraph/graphicsItems/PlotCurveItem.py b/pyqtgraph/graphicsItems/PlotCurveItem.py index 06f9bdee..150b755a 100644 --- a/pyqtgraph/graphicsItems/PlotCurveItem.py +++ b/pyqtgraph/graphicsItems/PlotCurveItem.py @@ -65,6 +65,7 @@ class PlotCurveItem(GraphicsObject): 'connect': 'all', 'mouseWidth': 8, # width of shape responding to mouse click 'compositionMode': None, + 'skipFiniteCheck': True } if 'pen' not in kargs: self.opts['pen'] = fn.mkPen('w') @@ -336,6 +337,11 @@ class PlotCurveItem(GraphicsObject): connectivity, specify an array of boolean values. compositionMode See :func:`setCompositionMode `. + skipFiniteCheck Optimization parameter that can speed up plot time by + telling the painter to not check and compensate for NaN + values. If set to True, and NaN values exist, the data + may not be displayed or your plot will take a + significant performance hit. Defaults to False. =============== ======================================================== If non-keyword arguments are used, they will be interpreted as @@ -373,6 +379,7 @@ class PlotCurveItem(GraphicsObject): if data.dtype.kind == 'c': raise Exception("Can not plot complex data types.") + 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 @@ -421,6 +428,8 @@ class PlotCurveItem(GraphicsObject): if 'antialias' in kargs: self.opts['antialias'] = kargs['antialias'] + self.opts['skipFiniteCheck'] = kargs.get('skipFiniteCheck', False) + profiler('set') self.update() profiler('update') @@ -458,10 +467,12 @@ class PlotCurveItem(GraphicsObject): y[0] = self.opts['fillLevel'] y[-1] = self.opts['fillLevel'] - path = fn.arrayToQPath(x, y, connect=self.opts['connect']) - - return path - + return fn.arrayToQPath( + x, + y, + connect=self.opts['connect'], + finiteCheck=not self.opts['skipFiniteCheck'] + ) def getPath(self): if self.path is None: diff --git a/pyqtgraph/graphicsItems/PlotDataItem.py b/pyqtgraph/graphicsItems/PlotDataItem.py index c36f4ed1..eb883c22 100644 --- a/pyqtgraph/graphicsItems/PlotDataItem.py +++ b/pyqtgraph/graphicsItems/PlotDataItem.py @@ -140,6 +140,11 @@ class PlotDataItem(GraphicsObject): at any time. dynamicRangeLimit (float or None) Limit off-screen positions of data points at large magnification to avoids display errors. Disabled if None. + skipFiniteCheck (bool) Optimization parameter that can speed up plot time by + telling the painter to not check and compensate for NaN + values. If set to True, and NaN values exist, the data + may not be displayed or your plot will take a + significant performance hit. Defaults to False. identical *deprecated* ================= ===================================================================== @@ -210,7 +215,7 @@ class PlotDataItem(GraphicsObject): 'clipToView': False, 'dynamicRangeLimit': 1e6, 'dynamicRangeHyst': 3.0, - + 'skipFiniteCheck': False, 'data': None, } self.setCurveClickable(kargs.get('clickable', False)) @@ -605,11 +610,29 @@ class PlotDataItem(GraphicsObject): scatterArgs = {} if styleUpdate: # repeat style arguments only when changed - for k,v in [('pen','pen'), ('shadowPen','shadowPen'), ('fillLevel','fillLevel'), ('fillOutline', 'fillOutline'), ('fillBrush', 'brush'), ('antialias', 'antialias'), ('connect', 'connect'), ('stepMode', 'stepMode')]: + for k, v in [ + ('pen','pen'), + ('shadowPen','shadowPen'), + ('fillLevel','fillLevel'), + ('fillOutline', 'fillOutline'), + ('fillBrush', 'brush'), + ('antialias', 'antialias'), + ('connect', 'connect'), + ('stepMode', 'stepMode'), + ('skipFiniteCheck', 'skipFiniteCheck') + ]: if k in self.opts: curveArgs[v] = self.opts[k] - for k,v in [('symbolPen','pen'), ('symbolBrush','brush'), ('symbol','symbol'), ('symbolSize', 'size'), ('data', 'data'), ('pxMode', 'pxMode'), ('antialias', 'antialias')]: + for k, v in [ + ('symbolPen','pen'), + ('symbolBrush','brush'), + ('symbol','symbol'), + ('symbolSize', 'size'), + ('data', 'data'), + ('pxMode', 'pxMode'), + ('antialias', 'antialias') + ]: if k in self.opts: scatterArgs[v] = self.opts[k]