Perform finiteCheck on PlotCurveItem.setData
The check for NaN values in arrayToQPath is expensive, this change attempts to do the check one time, and if no NaN values are present, an optional flag is passed along telling arrayToQPath that the check can be skipped
This commit is contained in:
parent
f08d239578
commit
7860d641ab
@ -1678,7 +1678,7 @@ def downsample(data, n, axis=0, xvals='subsample'):
|
|||||||
return MetaArray(d2, info=info)
|
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.
|
"""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
|
The *connect* argument may be 'all', indicating that each point should be
|
||||||
connected to the next; 'pairs', indicating that each pair of points
|
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.
|
# Qt version 5.12.3; these must now be manually cleaned out.
|
||||||
isfinite = None
|
isfinite = None
|
||||||
qtver = [int(x) for x in QtVersion.split('.')]
|
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)
|
isfinite = np.isfinite(x) & np.isfinite(y)
|
||||||
if not np.all(isfinite):
|
if not np.all(isfinite):
|
||||||
# credit: Divakar https://stackoverflow.com/a/41191127/643629
|
# credit: Divakar https://stackoverflow.com/a/41191127/643629
|
||||||
|
@ -65,6 +65,7 @@ class PlotCurveItem(GraphicsObject):
|
|||||||
'connect': 'all',
|
'connect': 'all',
|
||||||
'mouseWidth': 8, # width of shape responding to mouse click
|
'mouseWidth': 8, # width of shape responding to mouse click
|
||||||
'compositionMode': None,
|
'compositionMode': None,
|
||||||
|
'skipFiniteCheck': True
|
||||||
}
|
}
|
||||||
if 'pen' not in kargs:
|
if 'pen' not in kargs:
|
||||||
self.opts['pen'] = fn.mkPen('w')
|
self.opts['pen'] = fn.mkPen('w')
|
||||||
@ -336,6 +337,11 @@ class PlotCurveItem(GraphicsObject):
|
|||||||
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>`.
|
||||||
|
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
|
If non-keyword arguments are used, they will be interpreted as
|
||||||
@ -373,6 +379,7 @@ class PlotCurveItem(GraphicsObject):
|
|||||||
if data.dtype.kind == 'c':
|
if data.dtype.kind == 'c':
|
||||||
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
|
||||||
@ -421,6 +428,8 @@ class PlotCurveItem(GraphicsObject):
|
|||||||
if 'antialias' in kargs:
|
if 'antialias' in kargs:
|
||||||
self.opts['antialias'] = kargs['antialias']
|
self.opts['antialias'] = kargs['antialias']
|
||||||
|
|
||||||
|
self.opts['skipFiniteCheck'] = kargs.get('skipFiniteCheck', False)
|
||||||
|
|
||||||
profiler('set')
|
profiler('set')
|
||||||
self.update()
|
self.update()
|
||||||
profiler('update')
|
profiler('update')
|
||||||
@ -458,10 +467,12 @@ class PlotCurveItem(GraphicsObject):
|
|||||||
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'])
|
return fn.arrayToQPath(
|
||||||
|
x,
|
||||||
return path
|
y,
|
||||||
|
connect=self.opts['connect'],
|
||||||
|
finiteCheck=not self.opts['skipFiniteCheck']
|
||||||
|
)
|
||||||
|
|
||||||
def getPath(self):
|
def getPath(self):
|
||||||
if self.path is None:
|
if self.path is None:
|
||||||
|
@ -140,6 +140,11 @@ class PlotDataItem(GraphicsObject):
|
|||||||
at any time.
|
at any time.
|
||||||
dynamicRangeLimit (float or None) Limit off-screen positions of data points at large
|
dynamicRangeLimit (float or None) Limit off-screen positions of data points at large
|
||||||
magnification to avoids display errors. Disabled if None.
|
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*
|
identical *deprecated*
|
||||||
================= =====================================================================
|
================= =====================================================================
|
||||||
|
|
||||||
@ -210,7 +215,7 @@ class PlotDataItem(GraphicsObject):
|
|||||||
'clipToView': False,
|
'clipToView': False,
|
||||||
'dynamicRangeLimit': 1e6,
|
'dynamicRangeLimit': 1e6,
|
||||||
'dynamicRangeHyst': 3.0,
|
'dynamicRangeHyst': 3.0,
|
||||||
|
'skipFiniteCheck': False,
|
||||||
'data': None,
|
'data': None,
|
||||||
}
|
}
|
||||||
self.setCurveClickable(kargs.get('clickable', False))
|
self.setCurveClickable(kargs.get('clickable', False))
|
||||||
@ -605,11 +610,29 @@ class PlotDataItem(GraphicsObject):
|
|||||||
scatterArgs = {}
|
scatterArgs = {}
|
||||||
|
|
||||||
if styleUpdate: # repeat style arguments only when changed
|
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:
|
if k in self.opts:
|
||||||
curveArgs[v] = self.opts[k]
|
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:
|
if k in self.opts:
|
||||||
scatterArgs[v] = self.opts[k]
|
scatterArgs[v] = self.opts[k]
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user