Merge branch 'profilers' into develop
New Profiler class from Antony Lee: * Simpler API (with backward compatibility) * Individual Profilers can be enabled by environmental variable PYQTGRAPHPROFILE
This commit is contained in:
commit
6d57792dc6
@ -5,6 +5,8 @@ Copyright 2010 Luke Campagnola
|
|||||||
Distributed under MIT/X11 license. See license.txt for more infomation.
|
Distributed under MIT/X11 license. See license.txt for more infomation.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
import sys, traceback, time, gc, re, types, weakref, inspect, os, cProfile
|
import sys, traceback, time, gc, re, types, weakref, inspect, os, cProfile
|
||||||
from . import ptime
|
from . import ptime
|
||||||
from numpy import ndarray
|
from numpy import ndarray
|
||||||
@ -365,82 +367,125 @@ class GarbageWatcher(object):
|
|||||||
return self.objs[item]
|
return self.objs[item]
|
||||||
|
|
||||||
|
|
||||||
class Profiler:
|
|
||||||
|
|
||||||
|
class Profiler(object):
|
||||||
"""Simple profiler allowing measurement of multiple time intervals.
|
"""Simple profiler allowing measurement of multiple time intervals.
|
||||||
Arguments:
|
|
||||||
msg: message to print at start and finish of profiling
|
By default, profilers are disabled. To enable profiling, set the
|
||||||
disabled: If true, profiler does nothing (so you can leave it in place)
|
environment variable `PYQTGRAPHPROFILE` to a comma-separated list of
|
||||||
delayed: If true, all messages are printed after call to finish()
|
fully-qualified names of profiled functions.
|
||||||
(this can result in more accurate time step measurements)
|
|
||||||
globalDelay: if True, all nested profilers delay printing until the top level finishes
|
Calling a profiler registers a message (defaulting to an increasing
|
||||||
|
counter) that contains the time elapsed since the last call. When the
|
||||||
|
profiler is about to be garbage-collected, the messages are passed to the
|
||||||
|
outer profiler if one is running, or printed to stdout otherwise.
|
||||||
|
|
||||||
|
If `delayed` is set to False, messages are immediately printed instead.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
prof = Profiler('Function')
|
def function(...):
|
||||||
... do stuff ...
|
profiler = Profiler()
|
||||||
prof.mark('did stuff')
|
... do stuff ...
|
||||||
... do other stuff ...
|
profiler('did stuff')
|
||||||
prof.mark('did other stuff')
|
... do other stuff ...
|
||||||
prof.finish()
|
profiler('did other stuff')
|
||||||
|
# profiler is garbage-collected and flushed at function end
|
||||||
|
|
||||||
|
If this function is a method of class C, setting `PYQTGRAPHPROFILE` to
|
||||||
|
"C.function" (without the module name) will enable this profiler.
|
||||||
|
|
||||||
|
For regular functions, use the qualified name of the function, stripping
|
||||||
|
only the initial "pyqtgraph." prefix from the module.
|
||||||
"""
|
"""
|
||||||
depth = 0
|
|
||||||
msgs = []
|
|
||||||
|
|
||||||
def __init__(self, msg="Profiler", disabled=False, delayed=True, globalDelay=True):
|
_profilers = os.environ.get("PYQTGRAPHPROFILE", "")
|
||||||
self.disabled = disabled
|
_depth = 0
|
||||||
if disabled:
|
_msgs = []
|
||||||
return
|
|
||||||
|
|
||||||
self.markCount = 0
|
class DisabledProfiler(object):
|
||||||
self.finished = False
|
def __init__(self, *args, **kwds):
|
||||||
self.depth = Profiler.depth
|
pass
|
||||||
Profiler.depth += 1
|
def __call__(self, *args):
|
||||||
if not globalDelay:
|
pass
|
||||||
self.msgs = []
|
def finish(self):
|
||||||
self.delayed = delayed
|
pass
|
||||||
self.msg = " "*self.depth + msg
|
def mark(self, msg=None):
|
||||||
msg2 = self.msg + " >>> Started"
|
pass
|
||||||
if self.delayed:
|
_disabledProfiler = DisabledProfiler()
|
||||||
self.msgs.append(msg2)
|
|
||||||
else:
|
|
||||||
print(msg2)
|
if _profilers:
|
||||||
self.t0 = ptime.time()
|
_profilers = _profilers.split(",")
|
||||||
self.t1 = self.t0
|
def __new__(cls, msg=None, disabled='env', delayed=True):
|
||||||
|
"""Optionally create a new profiler based on caller's qualname.
|
||||||
|
"""
|
||||||
|
if disabled is True:
|
||||||
|
return cls._disabledProfiler
|
||||||
|
|
||||||
|
# determine the qualified name of the caller function
|
||||||
|
caller_frame = sys._getframe(1)
|
||||||
|
try:
|
||||||
|
caller_object_type = type(caller_frame.f_locals["self"])
|
||||||
|
except KeyError: # we are in a regular function
|
||||||
|
qualifier = caller_frame.f_globals["__name__"].split(".", 1)[1]
|
||||||
|
else: # we are in a method
|
||||||
|
qualifier = caller_object_type.__name__
|
||||||
|
func_qualname = qualifier + "." + caller_frame.f_code.co_name
|
||||||
|
if func_qualname not in cls._profilers: # don't do anything
|
||||||
|
return cls._disabledProfiler
|
||||||
|
# create an actual profiling object
|
||||||
|
cls._depth += 1
|
||||||
|
obj = super(Profiler, cls).__new__(cls)
|
||||||
|
obj._name = msg or func_qualname
|
||||||
|
obj._delayed = delayed
|
||||||
|
obj._markCount = 0
|
||||||
|
obj._finished = False
|
||||||
|
obj._firstTime = obj._lastTime = ptime.time()
|
||||||
|
obj._newMsg("> Entering " + obj._name)
|
||||||
|
return obj
|
||||||
|
else:
|
||||||
|
def __new__(cls, delayed=True):
|
||||||
|
return lambda msg=None: None
|
||||||
|
|
||||||
|
def __call__(self, msg=None):
|
||||||
|
"""Register or print a new message with timing information.
|
||||||
|
"""
|
||||||
|
if msg is None:
|
||||||
|
msg = str(self._markCount)
|
||||||
|
self._markCount += 1
|
||||||
|
newTime = ptime.time()
|
||||||
|
self._newMsg(" %s: %0.4f ms",
|
||||||
|
msg, (newTime - self._lastTime) * 1000)
|
||||||
|
self._lastTime = newTime
|
||||||
|
|
||||||
def mark(self, msg=None):
|
def mark(self, msg=None):
|
||||||
if self.disabled:
|
self(msg)
|
||||||
return
|
|
||||||
|
|
||||||
if msg is None:
|
def _newMsg(self, msg, *args):
|
||||||
msg = str(self.markCount)
|
msg = " " * (self._depth - 1) + msg
|
||||||
self.markCount += 1
|
if self._delayed:
|
||||||
|
self._msgs.append((msg, args))
|
||||||
t1 = ptime.time()
|
|
||||||
msg2 = " "+self.msg+" "+msg+" "+"%gms" % ((t1-self.t1)*1000)
|
|
||||||
if self.delayed:
|
|
||||||
self.msgs.append(msg2)
|
|
||||||
else:
|
else:
|
||||||
print(msg2)
|
print(msg % args)
|
||||||
self.t1 = ptime.time() ## don't measure time it took to print
|
|
||||||
|
def __del__(self):
|
||||||
|
self.finish()
|
||||||
|
|
||||||
def finish(self, msg=None):
|
def finish(self, msg=None):
|
||||||
if self.disabled or self.finished:
|
"""Add a final message; flush the message list if no parent profiler.
|
||||||
|
"""
|
||||||
|
if self._finished:
|
||||||
return
|
return
|
||||||
|
self._finished = True
|
||||||
if msg is not None:
|
if msg is not None:
|
||||||
self.mark(msg)
|
self(msg)
|
||||||
t1 = ptime.time()
|
self._newMsg("< Exiting %s, total time: %0.4f ms",
|
||||||
msg = self.msg + ' <<< Finished, total time: %gms' % ((t1-self.t0)*1000)
|
self._name, (ptime.time() - self._firstTime) * 1000)
|
||||||
if self.delayed:
|
type(self)._depth -= 1
|
||||||
self.msgs.append(msg)
|
if self._depth < 1 and self._msgs:
|
||||||
if self.depth == 0:
|
print("\n".join([m[0]%m[1] for m in self._msgs]))
|
||||||
for line in self.msgs:
|
type(self)._msgs = []
|
||||||
print(line)
|
|
||||||
Profiler.msgs = []
|
|
||||||
else:
|
|
||||||
print(msg)
|
|
||||||
Profiler.depth = self.depth
|
|
||||||
self.finished = True
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -156,7 +156,7 @@ def _generateItemSvg(item, nodes=None, root=None):
|
|||||||
##
|
##
|
||||||
## Both 2 and 3 can be addressed by drawing all items in world coordinates.
|
## Both 2 and 3 can be addressed by drawing all items in world coordinates.
|
||||||
|
|
||||||
prof = pg.debug.Profiler('generateItemSvg %s' % str(item), disabled=True)
|
profiler = pg.debug.Profiler()
|
||||||
|
|
||||||
if nodes is None: ## nodes maps all node IDs to their XML element.
|
if nodes is None: ## nodes maps all node IDs to their XML element.
|
||||||
## this allows us to ensure all elements receive unique names.
|
## this allows us to ensure all elements receive unique names.
|
||||||
@ -235,12 +235,12 @@ def _generateItemSvg(item, nodes=None, root=None):
|
|||||||
print(doc.toxml())
|
print(doc.toxml())
|
||||||
raise
|
raise
|
||||||
|
|
||||||
prof.mark('render')
|
profiler('render')
|
||||||
|
|
||||||
## Get rid of group transformation matrices by applying
|
## Get rid of group transformation matrices by applying
|
||||||
## transformation to inner coordinates
|
## transformation to inner coordinates
|
||||||
correctCoordinates(g1, item)
|
correctCoordinates(g1, item)
|
||||||
prof.mark('correct')
|
profiler('correct')
|
||||||
## make sure g1 has the transformation matrix
|
## make sure g1 has the transformation matrix
|
||||||
#m = (tr.m11(), tr.m12(), tr.m21(), tr.m22(), tr.m31(), tr.m32())
|
#m = (tr.m11(), tr.m12(), tr.m21(), tr.m22(), tr.m31(), tr.m32())
|
||||||
#g1.setAttribute('transform', "matrix(%f,%f,%f,%f,%f,%f)" % m)
|
#g1.setAttribute('transform', "matrix(%f,%f,%f,%f,%f,%f)" % m)
|
||||||
@ -290,7 +290,7 @@ def _generateItemSvg(item, nodes=None, root=None):
|
|||||||
childGroup = g1.ownerDocument.createElement('g')
|
childGroup = g1.ownerDocument.createElement('g')
|
||||||
childGroup.setAttribute('clip-path', 'url(#%s)' % clip)
|
childGroup.setAttribute('clip-path', 'url(#%s)' % clip)
|
||||||
g1.appendChild(childGroup)
|
g1.appendChild(childGroup)
|
||||||
prof.mark('clipping')
|
profiler('clipping')
|
||||||
|
|
||||||
## Add all child items as sub-elements.
|
## Add all child items as sub-elements.
|
||||||
childs.sort(key=lambda c: c.zValue())
|
childs.sort(key=lambda c: c.zValue())
|
||||||
@ -299,8 +299,7 @@ def _generateItemSvg(item, nodes=None, root=None):
|
|||||||
if cg is None:
|
if cg is None:
|
||||||
continue
|
continue
|
||||||
childGroup.appendChild(cg) ### this isn't quite right--some items draw below their parent (good enough for now)
|
childGroup.appendChild(cg) ### this isn't quite right--some items draw below their parent (good enough for now)
|
||||||
prof.mark('children')
|
profiler('children')
|
||||||
prof.finish()
|
|
||||||
return g1
|
return g1
|
||||||
|
|
||||||
def correctCoordinates(node, item):
|
def correctCoordinates(node, item):
|
||||||
|
@ -775,7 +775,7 @@ def makeARGB(data, lut=None, levels=None, scale=None, useRGBA=False):
|
|||||||
is BGRA).
|
is BGRA).
|
||||||
============ ==================================================================================
|
============ ==================================================================================
|
||||||
"""
|
"""
|
||||||
prof = debug.Profiler('functions.makeARGB', disabled=True)
|
profile = debug.Profiler()
|
||||||
|
|
||||||
if lut is not None and not isinstance(lut, np.ndarray):
|
if lut is not None and not isinstance(lut, np.ndarray):
|
||||||
lut = np.array(lut)
|
lut = np.array(lut)
|
||||||
@ -795,7 +795,7 @@ def makeARGB(data, lut=None, levels=None, scale=None, useRGBA=False):
|
|||||||
print(levels)
|
print(levels)
|
||||||
raise Exception("levels argument must be 1D or 2D.")
|
raise Exception("levels argument must be 1D or 2D.")
|
||||||
|
|
||||||
prof.mark('1')
|
profile()
|
||||||
|
|
||||||
if scale is None:
|
if scale is None:
|
||||||
if lut is not None:
|
if lut is not None:
|
||||||
@ -822,8 +822,8 @@ def makeARGB(data, lut=None, levels=None, scale=None, useRGBA=False):
|
|||||||
if minVal == maxVal:
|
if minVal == maxVal:
|
||||||
maxVal += 1e-16
|
maxVal += 1e-16
|
||||||
data = rescaleData(data, scale/(maxVal-minVal), minVal, dtype=int)
|
data = rescaleData(data, scale/(maxVal-minVal), minVal, dtype=int)
|
||||||
prof.mark('2')
|
|
||||||
|
|
||||||
|
profile()
|
||||||
|
|
||||||
## apply LUT if given
|
## apply LUT if given
|
||||||
if lut is not None:
|
if lut is not None:
|
||||||
@ -831,13 +831,13 @@ def makeARGB(data, lut=None, levels=None, scale=None, useRGBA=False):
|
|||||||
else:
|
else:
|
||||||
if data.dtype is not np.ubyte:
|
if data.dtype is not np.ubyte:
|
||||||
data = np.clip(data, 0, 255).astype(np.ubyte)
|
data = np.clip(data, 0, 255).astype(np.ubyte)
|
||||||
prof.mark('3')
|
|
||||||
|
|
||||||
|
profile()
|
||||||
|
|
||||||
## copy data into ARGB ordered array
|
## copy data into ARGB ordered array
|
||||||
imgData = np.empty(data.shape[:2]+(4,), dtype=np.ubyte)
|
imgData = np.empty(data.shape[:2]+(4,), dtype=np.ubyte)
|
||||||
|
|
||||||
prof.mark('4')
|
profile()
|
||||||
|
|
||||||
if useRGBA:
|
if useRGBA:
|
||||||
order = [0,1,2,3] ## array comes out RGBA
|
order = [0,1,2,3] ## array comes out RGBA
|
||||||
@ -857,7 +857,7 @@ def makeARGB(data, lut=None, levels=None, scale=None, useRGBA=False):
|
|||||||
for i in range(0, data.shape[2]):
|
for i in range(0, data.shape[2]):
|
||||||
imgData[..., i] = data[..., order[i]]
|
imgData[..., i] = data[..., order[i]]
|
||||||
|
|
||||||
prof.mark('5')
|
profile()
|
||||||
|
|
||||||
if data.ndim == 2 or data.shape[2] == 3:
|
if data.ndim == 2 or data.shape[2] == 3:
|
||||||
alpha = False
|
alpha = False
|
||||||
@ -865,9 +865,7 @@ def makeARGB(data, lut=None, levels=None, scale=None, useRGBA=False):
|
|||||||
else:
|
else:
|
||||||
alpha = True
|
alpha = True
|
||||||
|
|
||||||
prof.mark('6')
|
profile()
|
||||||
|
|
||||||
prof.finish()
|
|
||||||
return imgData, alpha
|
return imgData, alpha
|
||||||
|
|
||||||
|
|
||||||
@ -898,7 +896,7 @@ def makeQImage(imgData, alpha=None, copy=True, transpose=True):
|
|||||||
=========== ===================================================================
|
=========== ===================================================================
|
||||||
"""
|
"""
|
||||||
## create QImage from buffer
|
## create QImage from buffer
|
||||||
prof = debug.Profiler('functions.makeQImage', disabled=True)
|
profile = debug.Profiler()
|
||||||
|
|
||||||
## If we didn't explicitly specify alpha, check the array shape.
|
## If we didn't explicitly specify alpha, check the array shape.
|
||||||
if alpha is None:
|
if alpha is None:
|
||||||
@ -923,6 +921,8 @@ def makeQImage(imgData, alpha=None, copy=True, transpose=True):
|
|||||||
if transpose:
|
if transpose:
|
||||||
imgData = imgData.transpose((1, 0, 2)) ## QImage expects the row/column order to be opposite
|
imgData = imgData.transpose((1, 0, 2)) ## QImage expects the row/column order to be opposite
|
||||||
|
|
||||||
|
profile()
|
||||||
|
|
||||||
if not imgData.flags['C_CONTIGUOUS']:
|
if not imgData.flags['C_CONTIGUOUS']:
|
||||||
if copy is False:
|
if copy is False:
|
||||||
extra = ' (try setting transpose=False)' if transpose else ''
|
extra = ' (try setting transpose=False)' if transpose else ''
|
||||||
@ -963,11 +963,10 @@ def makeQImage(imgData, alpha=None, copy=True, transpose=True):
|
|||||||
#except AttributeError: ## happens when image data is non-contiguous
|
#except AttributeError: ## happens when image data is non-contiguous
|
||||||
#buf = imgData.data
|
#buf = imgData.data
|
||||||
|
|
||||||
#prof.mark('1')
|
#profiler()
|
||||||
#qimage = QtGui.QImage(buf, imgData.shape[1], imgData.shape[0], imgFormat)
|
#qimage = QtGui.QImage(buf, imgData.shape[1], imgData.shape[0], imgFormat)
|
||||||
#prof.mark('2')
|
#profiler()
|
||||||
#qimage.data = imgData
|
#qimage.data = imgData
|
||||||
#prof.finish()
|
|
||||||
#return qimage
|
#return qimage
|
||||||
|
|
||||||
def imageToArray(img, copy=False, transpose=True):
|
def imageToArray(img, copy=False, transpose=True):
|
||||||
@ -1087,16 +1086,16 @@ def arrayToQPath(x, y, connect='all'):
|
|||||||
|
|
||||||
path = QtGui.QPainterPath()
|
path = QtGui.QPainterPath()
|
||||||
|
|
||||||
#prof = debug.Profiler('PlotCurveItem.generatePath', disabled=True)
|
#profiler = debug.Profiler()
|
||||||
n = x.shape[0]
|
n = x.shape[0]
|
||||||
# create empty array, pad with extra space on either end
|
# create empty array, pad with extra space on either end
|
||||||
arr = np.empty(n+2, dtype=[('x', '>f8'), ('y', '>f8'), ('c', '>i4')])
|
arr = np.empty(n+2, dtype=[('x', '>f8'), ('y', '>f8'), ('c', '>i4')])
|
||||||
# write first two integers
|
# write first two integers
|
||||||
#prof.mark('allocate empty')
|
#profiler('allocate empty')
|
||||||
byteview = arr.view(dtype=np.ubyte)
|
byteview = arr.view(dtype=np.ubyte)
|
||||||
byteview[:12] = 0
|
byteview[:12] = 0
|
||||||
byteview.data[12:20] = struct.pack('>ii', n, 0)
|
byteview.data[12:20] = struct.pack('>ii', n, 0)
|
||||||
#prof.mark('pack header')
|
#profiler('pack header')
|
||||||
# Fill array with vertex values
|
# Fill array with vertex values
|
||||||
arr[1:-1]['x'] = x
|
arr[1:-1]['x'] = x
|
||||||
arr[1:-1]['y'] = y
|
arr[1:-1]['y'] = y
|
||||||
@ -1117,11 +1116,11 @@ def arrayToQPath(x, y, connect='all'):
|
|||||||
else:
|
else:
|
||||||
raise Exception('connect argument must be "all", "pairs", or array')
|
raise Exception('connect argument must be "all", "pairs", or array')
|
||||||
|
|
||||||
#prof.mark('fill array')
|
#profiler('fill array')
|
||||||
# write last 0
|
# write last 0
|
||||||
lastInd = 20*(n+1)
|
lastInd = 20*(n+1)
|
||||||
byteview.data[lastInd:lastInd+4] = struct.pack('>i', 0)
|
byteview.data[lastInd:lastInd+4] = struct.pack('>i', 0)
|
||||||
#prof.mark('footer')
|
#profiler('footer')
|
||||||
# create datastream object and stream into path
|
# create datastream object and stream into path
|
||||||
|
|
||||||
## Avoiding this method because QByteArray(str) leaks memory in PySide
|
## Avoiding this method because QByteArray(str) leaks memory in PySide
|
||||||
@ -1132,13 +1131,11 @@ def arrayToQPath(x, y, connect='all'):
|
|||||||
buf = QtCore.QByteArray.fromRawData(path.strn)
|
buf = QtCore.QByteArray.fromRawData(path.strn)
|
||||||
except TypeError:
|
except TypeError:
|
||||||
buf = QtCore.QByteArray(bytes(path.strn))
|
buf = QtCore.QByteArray(bytes(path.strn))
|
||||||
#prof.mark('create buffer')
|
#profiler('create buffer')
|
||||||
ds = QtCore.QDataStream(buf)
|
ds = QtCore.QDataStream(buf)
|
||||||
|
|
||||||
ds >> path
|
ds >> path
|
||||||
#prof.mark('load')
|
#profiler('load')
|
||||||
|
|
||||||
#prof.finish()
|
|
||||||
|
|
||||||
return path
|
return path
|
||||||
|
|
||||||
@ -1865,7 +1862,7 @@ def isosurface(data, level):
|
|||||||
faces = np.empty((totFaces, 3), dtype=np.uint32)
|
faces = np.empty((totFaces, 3), dtype=np.uint32)
|
||||||
ptr = 0
|
ptr = 0
|
||||||
#import debug
|
#import debug
|
||||||
#p = debug.Profiler('isosurface', disabled=False)
|
#p = debug.Profiler()
|
||||||
|
|
||||||
## this helps speed up an indexing operation later on
|
## this helps speed up an indexing operation later on
|
||||||
cs = np.array(cutEdges.strides)//cutEdges.itemsize
|
cs = np.array(cutEdges.strides)//cutEdges.itemsize
|
||||||
@ -1877,32 +1874,32 @@ def isosurface(data, level):
|
|||||||
|
|
||||||
for i in range(1,6):
|
for i in range(1,6):
|
||||||
### expensive:
|
### expensive:
|
||||||
#p.mark('1')
|
#profiler()
|
||||||
cells = np.argwhere(nFaces == i) ## all cells which require i faces (argwhere is expensive)
|
cells = np.argwhere(nFaces == i) ## all cells which require i faces (argwhere is expensive)
|
||||||
#p.mark('2')
|
#profiler()
|
||||||
if cells.shape[0] == 0:
|
if cells.shape[0] == 0:
|
||||||
continue
|
continue
|
||||||
#cellInds = index[(cells*ins[np.newaxis,:]).sum(axis=1)]
|
#cellInds = index[(cells*ins[np.newaxis,:]).sum(axis=1)]
|
||||||
cellInds = index[cells[:,0], cells[:,1], cells[:,2]] ## index values of cells to process for this round
|
cellInds = index[cells[:,0], cells[:,1], cells[:,2]] ## index values of cells to process for this round
|
||||||
#p.mark('3')
|
#profiler()
|
||||||
|
|
||||||
### expensive:
|
### expensive:
|
||||||
verts = faceShiftTables[i][cellInds]
|
verts = faceShiftTables[i][cellInds]
|
||||||
#p.mark('4')
|
#profiler()
|
||||||
verts[...,:3] += cells[:,np.newaxis,np.newaxis,:] ## we now have indexes into cutEdges
|
verts[...,:3] += cells[:,np.newaxis,np.newaxis,:] ## we now have indexes into cutEdges
|
||||||
verts = verts.reshape((verts.shape[0]*i,)+verts.shape[2:])
|
verts = verts.reshape((verts.shape[0]*i,)+verts.shape[2:])
|
||||||
#p.mark('5')
|
#profiler()
|
||||||
|
|
||||||
### expensive:
|
### expensive:
|
||||||
#print verts.shape
|
#print verts.shape
|
||||||
verts = (verts * cs[np.newaxis, np.newaxis, :]).sum(axis=2)
|
verts = (verts * cs[np.newaxis, np.newaxis, :]).sum(axis=2)
|
||||||
#vertInds = cutEdges[verts[...,0], verts[...,1], verts[...,2], verts[...,3]] ## and these are the vertex indexes we want.
|
#vertInds = cutEdges[verts[...,0], verts[...,1], verts[...,2], verts[...,3]] ## and these are the vertex indexes we want.
|
||||||
vertInds = cutEdges[verts]
|
vertInds = cutEdges[verts]
|
||||||
#p.mark('6')
|
#profiler()
|
||||||
nv = vertInds.shape[0]
|
nv = vertInds.shape[0]
|
||||||
#p.mark('7')
|
#profiler()
|
||||||
faces[ptr:ptr+nv] = vertInds #.reshape((nv, 3))
|
faces[ptr:ptr+nv] = vertInds #.reshape((nv, 3))
|
||||||
#p.mark('8')
|
#profiler()
|
||||||
ptr += nv
|
ptr += nv
|
||||||
|
|
||||||
return vertexes, faces
|
return vertexes, faces
|
||||||
|
@ -404,25 +404,22 @@ class AxisItem(GraphicsWidget):
|
|||||||
return self.mapRectFromParent(self.geometry()) | linkedView.mapRectToItem(self, linkedView.boundingRect())
|
return self.mapRectFromParent(self.geometry()) | linkedView.mapRectToItem(self, linkedView.boundingRect())
|
||||||
|
|
||||||
def paint(self, p, opt, widget):
|
def paint(self, p, opt, widget):
|
||||||
prof = debug.Profiler('AxisItem.paint', disabled=True)
|
profiler = debug.Profiler()
|
||||||
if self.picture is None:
|
if self.picture is None:
|
||||||
try:
|
try:
|
||||||
picture = QtGui.QPicture()
|
picture = QtGui.QPicture()
|
||||||
painter = QtGui.QPainter(picture)
|
painter = QtGui.QPainter(picture)
|
||||||
specs = self.generateDrawSpecs(painter)
|
specs = self.generateDrawSpecs(painter)
|
||||||
prof.mark('generate specs')
|
profiler('generate specs')
|
||||||
if specs is not None:
|
if specs is not None:
|
||||||
self.drawPicture(painter, *specs)
|
self.drawPicture(painter, *specs)
|
||||||
prof.mark('draw picture')
|
profiler('draw picture')
|
||||||
finally:
|
finally:
|
||||||
painter.end()
|
painter.end()
|
||||||
self.picture = picture
|
self.picture = picture
|
||||||
#p.setRenderHint(p.Antialiasing, False) ## Sometimes we get a segfault here ???
|
#p.setRenderHint(p.Antialiasing, False) ## Sometimes we get a segfault here ???
|
||||||
#p.setRenderHint(p.TextAntialiasing, True)
|
#p.setRenderHint(p.TextAntialiasing, True)
|
||||||
self.picture.play(p)
|
self.picture.play(p)
|
||||||
prof.finish()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def setTicks(self, ticks):
|
def setTicks(self, ticks):
|
||||||
"""Explicitly determine which ticks to display.
|
"""Explicitly determine which ticks to display.
|
||||||
@ -626,7 +623,7 @@ class AxisItem(GraphicsWidget):
|
|||||||
be drawn, then generates from this a set of drawing commands to be
|
be drawn, then generates from this a set of drawing commands to be
|
||||||
interpreted by drawPicture().
|
interpreted by drawPicture().
|
||||||
"""
|
"""
|
||||||
prof = debug.Profiler("AxisItem.generateDrawSpecs", disabled=True)
|
profiler = debug.Profiler()
|
||||||
|
|
||||||
#bounds = self.boundingRect()
|
#bounds = self.boundingRect()
|
||||||
bounds = self.mapRectFromParent(self.geometry())
|
bounds = self.mapRectFromParent(self.geometry())
|
||||||
@ -706,7 +703,7 @@ class AxisItem(GraphicsWidget):
|
|||||||
xMin = min(xRange)
|
xMin = min(xRange)
|
||||||
xMax = max(xRange)
|
xMax = max(xRange)
|
||||||
|
|
||||||
prof.mark('init')
|
profiler('init')
|
||||||
|
|
||||||
tickPositions = [] # remembers positions of previously drawn ticks
|
tickPositions = [] # remembers positions of previously drawn ticks
|
||||||
|
|
||||||
@ -744,7 +741,7 @@ class AxisItem(GraphicsWidget):
|
|||||||
color.setAlpha(lineAlpha)
|
color.setAlpha(lineAlpha)
|
||||||
tickPen.setColor(color)
|
tickPen.setColor(color)
|
||||||
tickSpecs.append((tickPen, Point(p1), Point(p2)))
|
tickSpecs.append((tickPen, Point(p1), Point(p2)))
|
||||||
prof.mark('compute ticks')
|
profiler('compute ticks')
|
||||||
|
|
||||||
## This is where the long axis line should be drawn
|
## This is where the long axis line should be drawn
|
||||||
|
|
||||||
@ -857,7 +854,7 @@ class AxisItem(GraphicsWidget):
|
|||||||
#p.setPen(self.pen())
|
#p.setPen(self.pen())
|
||||||
#p.drawText(rect, textFlags, vstr)
|
#p.drawText(rect, textFlags, vstr)
|
||||||
textSpecs.append((rect, textFlags, vstr))
|
textSpecs.append((rect, textFlags, vstr))
|
||||||
prof.mark('compute text')
|
profiler('compute text')
|
||||||
|
|
||||||
## update max text size if needed.
|
## update max text size if needed.
|
||||||
self._updateMaxTextSize(textSize2)
|
self._updateMaxTextSize(textSize2)
|
||||||
@ -865,7 +862,7 @@ class AxisItem(GraphicsWidget):
|
|||||||
return (axisSpec, tickSpecs, textSpecs)
|
return (axisSpec, tickSpecs, textSpecs)
|
||||||
|
|
||||||
def drawPicture(self, p, axisSpec, tickSpecs, textSpecs):
|
def drawPicture(self, p, axisSpec, tickSpecs, textSpecs):
|
||||||
prof = debug.Profiler("AxisItem.drawPicture", disabled=True)
|
profiler = debug.Profiler()
|
||||||
|
|
||||||
p.setRenderHint(p.Antialiasing, False)
|
p.setRenderHint(p.Antialiasing, False)
|
||||||
p.setRenderHint(p.TextAntialiasing, True)
|
p.setRenderHint(p.TextAntialiasing, True)
|
||||||
@ -880,7 +877,7 @@ class AxisItem(GraphicsWidget):
|
|||||||
for pen, p1, p2 in tickSpecs:
|
for pen, p1, p2 in tickSpecs:
|
||||||
p.setPen(pen)
|
p.setPen(pen)
|
||||||
p.drawLine(p1, p2)
|
p.drawLine(p1, p2)
|
||||||
prof.mark('draw ticks')
|
profiler('draw ticks')
|
||||||
|
|
||||||
## Draw all text
|
## Draw all text
|
||||||
if self.tickFont is not None:
|
if self.tickFont is not None:
|
||||||
@ -889,9 +886,7 @@ class AxisItem(GraphicsWidget):
|
|||||||
for rect, flags, text in textSpecs:
|
for rect, flags, text in textSpecs:
|
||||||
p.drawText(rect, flags, text)
|
p.drawText(rect, flags, text)
|
||||||
#p.drawRect(rect)
|
#p.drawRect(rect)
|
||||||
|
profiler('draw text')
|
||||||
prof.mark('draw text')
|
|
||||||
prof.finish()
|
|
||||||
|
|
||||||
def show(self):
|
def show(self):
|
||||||
|
|
||||||
|
@ -184,19 +184,18 @@ class HistogramLUTItem(GraphicsWidget):
|
|||||||
self.update()
|
self.update()
|
||||||
|
|
||||||
def imageChanged(self, autoLevel=False, autoRange=False):
|
def imageChanged(self, autoLevel=False, autoRange=False):
|
||||||
prof = debug.Profiler('HistogramLUTItem.imageChanged', disabled=True)
|
profiler = debug.Profiler()
|
||||||
h = self.imageItem.getHistogram()
|
h = self.imageItem.getHistogram()
|
||||||
prof.mark('get histogram')
|
profiler('get histogram')
|
||||||
if h[0] is None:
|
if h[0] is None:
|
||||||
return
|
return
|
||||||
self.plot.setData(*h)
|
self.plot.setData(*h)
|
||||||
prof.mark('set plot')
|
profiler('set plot')
|
||||||
if autoLevel:
|
if autoLevel:
|
||||||
mn = h[0][0]
|
mn = h[0][0]
|
||||||
mx = h[0][-1]
|
mx = h[0][-1]
|
||||||
self.region.setRegion([mn, mx])
|
self.region.setRegion([mn, mx])
|
||||||
prof.mark('set region')
|
profiler('set region')
|
||||||
prof.finish()
|
|
||||||
|
|
||||||
def getLevels(self):
|
def getLevels(self):
|
||||||
return self.region.getRegion()
|
return self.region.getRegion()
|
||||||
|
@ -188,7 +188,7 @@ class ImageItem(GraphicsObject):
|
|||||||
border Sets the pen used when drawing the image border. Default is None.
|
border Sets the pen used when drawing the image border. Default is None.
|
||||||
================= =========================================================================
|
================= =========================================================================
|
||||||
"""
|
"""
|
||||||
prof = debug.Profiler('ImageItem.setImage', disabled=True)
|
profile = debug.Profiler()
|
||||||
|
|
||||||
gotNewData = False
|
gotNewData = False
|
||||||
if image is None:
|
if image is None:
|
||||||
@ -202,7 +202,7 @@ class ImageItem(GraphicsObject):
|
|||||||
self.prepareGeometryChange()
|
self.prepareGeometryChange()
|
||||||
self.informViewBoundsChanged()
|
self.informViewBoundsChanged()
|
||||||
|
|
||||||
prof.mark('1')
|
profile()
|
||||||
|
|
||||||
if autoLevels is None:
|
if autoLevels is None:
|
||||||
if 'levels' in kargs:
|
if 'levels' in kargs:
|
||||||
@ -218,23 +218,22 @@ class ImageItem(GraphicsObject):
|
|||||||
mn = 0
|
mn = 0
|
||||||
mx = 255
|
mx = 255
|
||||||
kargs['levels'] = [mn,mx]
|
kargs['levels'] = [mn,mx]
|
||||||
prof.mark('2')
|
|
||||||
|
profile()
|
||||||
|
|
||||||
self.setOpts(update=False, **kargs)
|
self.setOpts(update=False, **kargs)
|
||||||
prof.mark('3')
|
|
||||||
|
profile()
|
||||||
|
|
||||||
self.qimage = None
|
self.qimage = None
|
||||||
self.update()
|
self.update()
|
||||||
prof.mark('4')
|
|
||||||
|
profile()
|
||||||
|
|
||||||
if gotNewData:
|
if gotNewData:
|
||||||
self.sigImageChanged.emit()
|
self.sigImageChanged.emit()
|
||||||
|
|
||||||
|
|
||||||
prof.finish()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def updateImage(self, *args, **kargs):
|
def updateImage(self, *args, **kargs):
|
||||||
## used for re-rendering qimage from self.image.
|
## used for re-rendering qimage from self.image.
|
||||||
|
|
||||||
@ -250,7 +249,7 @@ class ImageItem(GraphicsObject):
|
|||||||
|
|
||||||
|
|
||||||
def render(self):
|
def render(self):
|
||||||
prof = debug.Profiler('ImageItem.render', disabled=True)
|
profile = debug.Profiler()
|
||||||
if self.image is None or self.image.size == 0:
|
if self.image is None or self.image.size == 0:
|
||||||
return
|
return
|
||||||
if isinstance(self.lut, collections.Callable):
|
if isinstance(self.lut, collections.Callable):
|
||||||
@ -262,28 +261,25 @@ class ImageItem(GraphicsObject):
|
|||||||
|
|
||||||
argb, alpha = fn.makeARGB(self.image.transpose((1, 0, 2)[:self.image.ndim]), lut=lut, levels=self.levels)
|
argb, alpha = fn.makeARGB(self.image.transpose((1, 0, 2)[:self.image.ndim]), lut=lut, levels=self.levels)
|
||||||
self.qimage = fn.makeQImage(argb, alpha, transpose=False)
|
self.qimage = fn.makeQImage(argb, alpha, transpose=False)
|
||||||
prof.finish()
|
|
||||||
|
|
||||||
|
|
||||||
def paint(self, p, *args):
|
def paint(self, p, *args):
|
||||||
prof = debug.Profiler('ImageItem.paint', disabled=True)
|
profile = debug.Profiler()
|
||||||
if self.image is None:
|
if self.image is None:
|
||||||
return
|
return
|
||||||
if self.qimage is None:
|
if self.qimage is None:
|
||||||
self.render()
|
self.render()
|
||||||
if self.qimage is None:
|
if self.qimage is None:
|
||||||
return
|
return
|
||||||
prof.mark('render QImage')
|
profile('render QImage')
|
||||||
if self.paintMode is not None:
|
if self.paintMode is not None:
|
||||||
p.setCompositionMode(self.paintMode)
|
p.setCompositionMode(self.paintMode)
|
||||||
prof.mark('set comp mode')
|
profile('set comp mode')
|
||||||
|
|
||||||
p.drawImage(QtCore.QPointF(0,0), self.qimage)
|
p.drawImage(QtCore.QPointF(0,0), self.qimage)
|
||||||
prof.mark('p.drawImage')
|
profile('p.drawImage')
|
||||||
if self.border is not None:
|
if self.border is not None:
|
||||||
p.setPen(self.border)
|
p.setPen(self.border)
|
||||||
p.drawRect(self.boundingRect())
|
p.drawRect(self.boundingRect())
|
||||||
prof.finish()
|
|
||||||
|
|
||||||
def save(self, fileName, *args):
|
def save(self, fileName, *args):
|
||||||
"""Save this image to file. Note that this saves the visible image (after scale/color changes), not the original data."""
|
"""Save this image to file. Note that this saves the visible image (after scale/color changes), not the original data."""
|
||||||
|
@ -140,12 +140,11 @@ class LinearRegionItem(UIGraphicsItem):
|
|||||||
return br.normalized()
|
return br.normalized()
|
||||||
|
|
||||||
def paint(self, p, *args):
|
def paint(self, p, *args):
|
||||||
#prof = debug.Profiler('LinearRegionItem.paint')
|
profiler = debug.Profiler()
|
||||||
UIGraphicsItem.paint(self, p, *args)
|
UIGraphicsItem.paint(self, p, *args)
|
||||||
p.setBrush(self.currentBrush)
|
p.setBrush(self.currentBrush)
|
||||||
p.setPen(fn.mkPen(None))
|
p.setPen(fn.mkPen(None))
|
||||||
p.drawRect(self.boundingRect())
|
p.drawRect(self.boundingRect())
|
||||||
#prof.finish()
|
|
||||||
|
|
||||||
def dataBounds(self, axis, frac=1.0, orthoRange=None):
|
def dataBounds(self, axis, frac=1.0, orthoRange=None):
|
||||||
if axis == self.orientation:
|
if axis == self.orientation:
|
||||||
|
@ -281,7 +281,7 @@ class PlotCurveItem(GraphicsObject):
|
|||||||
self.updateData(*args, **kargs)
|
self.updateData(*args, **kargs)
|
||||||
|
|
||||||
def updateData(self, *args, **kargs):
|
def updateData(self, *args, **kargs):
|
||||||
prof = debug.Profiler('PlotCurveItem.updateData', disabled=True)
|
profiler = debug.Profiler()
|
||||||
|
|
||||||
if len(args) == 1:
|
if len(args) == 1:
|
||||||
kargs['y'] = args[0]
|
kargs['y'] = args[0]
|
||||||
@ -304,7 +304,7 @@ class PlotCurveItem(GraphicsObject):
|
|||||||
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.")
|
||||||
|
|
||||||
prof.mark("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
|
||||||
@ -314,7 +314,7 @@ class PlotCurveItem(GraphicsObject):
|
|||||||
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)
|
||||||
|
|
||||||
prof.mark('copy')
|
profiler('copy')
|
||||||
|
|
||||||
if 'stepMode' in kargs:
|
if 'stepMode' in kargs:
|
||||||
self.opts['stepMode'] = kargs['stepMode']
|
self.opts['stepMode'] = kargs['stepMode']
|
||||||
@ -346,12 +346,11 @@ class PlotCurveItem(GraphicsObject):
|
|||||||
self.opts['antialias'] = kargs['antialias']
|
self.opts['antialias'] = kargs['antialias']
|
||||||
|
|
||||||
|
|
||||||
prof.mark('set')
|
profiler('set')
|
||||||
self.update()
|
self.update()
|
||||||
prof.mark('update')
|
profiler('update')
|
||||||
self.sigPlotChanged.emit(self)
|
self.sigPlotChanged.emit(self)
|
||||||
prof.mark('emit')
|
profiler('emit')
|
||||||
prof.finish()
|
|
||||||
|
|
||||||
def generatePath(self, x, y):
|
def generatePath(self, x, y):
|
||||||
if self.opts['stepMode']:
|
if self.opts['stepMode']:
|
||||||
@ -387,7 +386,7 @@ class PlotCurveItem(GraphicsObject):
|
|||||||
|
|
||||||
@pg.debug.warnOnException ## raising an exception here causes crash
|
@pg.debug.warnOnException ## raising an exception here causes crash
|
||||||
def paint(self, p, opt, widget):
|
def paint(self, p, opt, widget):
|
||||||
prof = debug.Profiler('PlotCurveItem.paint '+str(id(self)), disabled=True)
|
profiler = debug.Profiler()
|
||||||
if self.xData is None:
|
if self.xData is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -405,7 +404,7 @@ class PlotCurveItem(GraphicsObject):
|
|||||||
self.fillPath = None
|
self.fillPath = None
|
||||||
|
|
||||||
path = self.path
|
path = self.path
|
||||||
prof.mark('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)
|
||||||
@ -426,9 +425,9 @@ class PlotCurveItem(GraphicsObject):
|
|||||||
p2.closeSubpath()
|
p2.closeSubpath()
|
||||||
self.fillPath = p2
|
self.fillPath = p2
|
||||||
|
|
||||||
prof.mark('generate fill path')
|
profiler('generate fill path')
|
||||||
p.fillPath(self.fillPath, self.opts['brush'])
|
p.fillPath(self.fillPath, self.opts['brush'])
|
||||||
prof.mark('draw fill path')
|
profiler('draw fill path')
|
||||||
|
|
||||||
sp = fn.mkPen(self.opts['shadowPen'])
|
sp = fn.mkPen(self.opts['shadowPen'])
|
||||||
cp = fn.mkPen(self.opts['pen'])
|
cp = fn.mkPen(self.opts['pen'])
|
||||||
@ -451,10 +450,9 @@ class PlotCurveItem(GraphicsObject):
|
|||||||
p.drawPath(path)
|
p.drawPath(path)
|
||||||
p.setPen(cp)
|
p.setPen(cp)
|
||||||
p.drawPath(path)
|
p.drawPath(path)
|
||||||
prof.mark('drawPath')
|
profiler('drawPath')
|
||||||
|
|
||||||
#print "Render hints:", int(p.renderHints())
|
#print "Render hints:", int(p.renderHints())
|
||||||
prof.finish()
|
|
||||||
#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())
|
||||||
|
|
||||||
|
@ -333,7 +333,7 @@ class PlotDataItem(GraphicsObject):
|
|||||||
See :func:`__init__() <pyqtgraph.PlotDataItem.__init__>` for details; it accepts the same arguments.
|
See :func:`__init__() <pyqtgraph.PlotDataItem.__init__>` for details; it accepts the same arguments.
|
||||||
"""
|
"""
|
||||||
#self.clear()
|
#self.clear()
|
||||||
prof = debug.Profiler('PlotDataItem.setData (0x%x)' % id(self), disabled=True)
|
profiler = debug.Profiler()
|
||||||
y = None
|
y = None
|
||||||
x = None
|
x = None
|
||||||
if len(args) == 1:
|
if len(args) == 1:
|
||||||
@ -383,7 +383,7 @@ class PlotDataItem(GraphicsObject):
|
|||||||
if 'y' in kargs:
|
if 'y' in kargs:
|
||||||
y = kargs['y']
|
y = kargs['y']
|
||||||
|
|
||||||
prof.mark('interpret data')
|
profiler('interpret data')
|
||||||
## pull in all style arguments.
|
## pull in all style arguments.
|
||||||
## Use self.opts to fill in anything not present in kargs.
|
## Use self.opts to fill in anything not present in kargs.
|
||||||
|
|
||||||
@ -432,10 +432,10 @@ class PlotDataItem(GraphicsObject):
|
|||||||
self.xClean = self.yClean = None
|
self.xClean = self.yClean = None
|
||||||
self.xDisp = None
|
self.xDisp = None
|
||||||
self.yDisp = None
|
self.yDisp = None
|
||||||
prof.mark('set data')
|
profiler('set data')
|
||||||
|
|
||||||
self.updateItems()
|
self.updateItems()
|
||||||
prof.mark('update items')
|
profiler('update items')
|
||||||
|
|
||||||
self.informViewBoundsChanged()
|
self.informViewBoundsChanged()
|
||||||
#view = self.getViewBox()
|
#view = self.getViewBox()
|
||||||
@ -443,9 +443,7 @@ class PlotDataItem(GraphicsObject):
|
|||||||
#view.itemBoundsChanged(self) ## inform view so it can update its range if it wants
|
#view.itemBoundsChanged(self) ## inform view so it can update its range if it wants
|
||||||
|
|
||||||
self.sigPlotChanged.emit(self)
|
self.sigPlotChanged.emit(self)
|
||||||
prof.mark('emit')
|
profiler('emit')
|
||||||
prof.finish()
|
|
||||||
|
|
||||||
|
|
||||||
def updateItems(self):
|
def updateItems(self):
|
||||||
|
|
||||||
|
@ -339,9 +339,8 @@ class PlotItem(GraphicsWidget):
|
|||||||
self.ctrl.gridAlphaSlider.setValue(v)
|
self.ctrl.gridAlphaSlider.setValue(v)
|
||||||
|
|
||||||
#def paint(self, *args):
|
#def paint(self, *args):
|
||||||
#prof = debug.Profiler('PlotItem.paint', disabled=True)
|
#prof = debug.Profiler()
|
||||||
#QtGui.QGraphicsWidget.paint(self, *args)
|
#QtGui.QGraphicsWidget.paint(self, *args)
|
||||||
#prof.finish()
|
|
||||||
|
|
||||||
## bad idea.
|
## bad idea.
|
||||||
#def __getattr__(self, attr): ## wrap ms
|
#def __getattr__(self, attr): ## wrap ms
|
||||||
|
@ -219,7 +219,7 @@ class ScatterPlotItem(GraphicsObject):
|
|||||||
"""
|
"""
|
||||||
Accepts the same arguments as setData()
|
Accepts the same arguments as setData()
|
||||||
"""
|
"""
|
||||||
prof = debug.Profiler('ScatterPlotItem.__init__', disabled=True)
|
profiler = debug.Profiler()
|
||||||
GraphicsObject.__init__(self)
|
GraphicsObject.__init__(self)
|
||||||
|
|
||||||
self.picture = None # QPicture used for rendering when pxmode==False
|
self.picture = None # QPicture used for rendering when pxmode==False
|
||||||
@ -240,10 +240,9 @@ class ScatterPlotItem(GraphicsObject):
|
|||||||
self.setBrush(100,100,150, update=False)
|
self.setBrush(100,100,150, update=False)
|
||||||
self.setSymbol('o', update=False)
|
self.setSymbol('o', update=False)
|
||||||
self.setSize(7, update=False)
|
self.setSize(7, update=False)
|
||||||
prof.mark('1')
|
profiler()
|
||||||
self.setData(*args, **kargs)
|
self.setData(*args, **kargs)
|
||||||
prof.mark('setData')
|
profiler('setData')
|
||||||
prof.finish()
|
|
||||||
|
|
||||||
#self.setCacheMode(self.DeviceCoordinateCache)
|
#self.setCacheMode(self.DeviceCoordinateCache)
|
||||||
|
|
||||||
|
@ -1205,7 +1205,7 @@ class ViewBox(GraphicsWidget):
|
|||||||
[[xmin, xmax], [ymin, ymax]]
|
[[xmin, xmax], [ymin, ymax]]
|
||||||
Values may be None if there are no specific bounds for an axis.
|
Values may be None if there are no specific bounds for an axis.
|
||||||
"""
|
"""
|
||||||
prof = debug.Profiler('updateAutoRange', disabled=True)
|
profiler = debug.Profiler()
|
||||||
if items is None:
|
if items is None:
|
||||||
items = self.addedItems
|
items = self.addedItems
|
||||||
|
|
||||||
@ -1282,7 +1282,7 @@ class ViewBox(GraphicsWidget):
|
|||||||
range[0] = [min(bounds.left(), range[0][0]), max(bounds.right(), range[0][1])]
|
range[0] = [min(bounds.left(), range[0][0]), max(bounds.right(), range[0][1])]
|
||||||
else:
|
else:
|
||||||
range[0] = [bounds.left(), bounds.right()]
|
range[0] = [bounds.left(), bounds.right()]
|
||||||
prof.mark('2')
|
profiler()
|
||||||
|
|
||||||
#print "range", range
|
#print "range", range
|
||||||
|
|
||||||
@ -1307,9 +1307,6 @@ class ViewBox(GraphicsWidget):
|
|||||||
range[1][0] = min(range[1][0], bounds.top() - px*pxSize)
|
range[1][0] = min(range[1][0], bounds.top() - px*pxSize)
|
||||||
range[1][1] = max(range[1][1], bounds.bottom() + px*pxSize)
|
range[1][1] = max(range[1][1], bounds.bottom() + px*pxSize)
|
||||||
|
|
||||||
#print "final range", range
|
|
||||||
|
|
||||||
prof.finish()
|
|
||||||
return range
|
return range
|
||||||
|
|
||||||
def childrenBoundingRect(self, *args, **kwds):
|
def childrenBoundingRect(self, *args, **kwds):
|
||||||
|
@ -190,7 +190,7 @@ class ImageView(QtGui.QWidget):
|
|||||||
image data.
|
image data.
|
||||||
================== =======================================================================
|
================== =======================================================================
|
||||||
"""
|
"""
|
||||||
prof = debug.Profiler('ImageView.setImage', disabled=True)
|
profiler = debug.Profiler()
|
||||||
|
|
||||||
if hasattr(img, 'implements') and img.implements('MetaArray'):
|
if hasattr(img, 'implements') and img.implements('MetaArray'):
|
||||||
img = img.asarray()
|
img = img.asarray()
|
||||||
@ -209,7 +209,7 @@ class ImageView(QtGui.QWidget):
|
|||||||
else:
|
else:
|
||||||
self.tVals = np.arange(img.shape[0])
|
self.tVals = np.arange(img.shape[0])
|
||||||
|
|
||||||
prof.mark('1')
|
profiler()
|
||||||
|
|
||||||
if axes is None:
|
if axes is None:
|
||||||
if img.ndim == 2:
|
if img.ndim == 2:
|
||||||
@ -234,12 +234,8 @@ class ImageView(QtGui.QWidget):
|
|||||||
|
|
||||||
for x in ['t', 'x', 'y', 'c']:
|
for x in ['t', 'x', 'y', 'c']:
|
||||||
self.axes[x] = self.axes.get(x, None)
|
self.axes[x] = self.axes.get(x, None)
|
||||||
prof.mark('2')
|
|
||||||
|
|
||||||
self.imageDisp = None
|
profiler()
|
||||||
|
|
||||||
|
|
||||||
prof.mark('3')
|
|
||||||
|
|
||||||
self.currentIndex = 0
|
self.currentIndex = 0
|
||||||
self.updateImage(autoHistogramRange=autoHistogramRange)
|
self.updateImage(autoHistogramRange=autoHistogramRange)
|
||||||
@ -250,8 +246,8 @@ class ImageView(QtGui.QWidget):
|
|||||||
|
|
||||||
if self.ui.roiBtn.isChecked():
|
if self.ui.roiBtn.isChecked():
|
||||||
self.roiChanged()
|
self.roiChanged()
|
||||||
prof.mark('4')
|
|
||||||
|
|
||||||
|
profiler()
|
||||||
|
|
||||||
if self.axes['t'] is not None:
|
if self.axes['t'] is not None:
|
||||||
#self.ui.roiPlot.show()
|
#self.ui.roiPlot.show()
|
||||||
@ -271,7 +267,7 @@ class ImageView(QtGui.QWidget):
|
|||||||
s.setBounds([start, stop])
|
s.setBounds([start, stop])
|
||||||
#else:
|
#else:
|
||||||
#self.ui.roiPlot.hide()
|
#self.ui.roiPlot.hide()
|
||||||
prof.mark('5')
|
profiler()
|
||||||
|
|
||||||
self.imageItem.resetTransform()
|
self.imageItem.resetTransform()
|
||||||
if scale is not None:
|
if scale is not None:
|
||||||
@ -280,14 +276,14 @@ class ImageView(QtGui.QWidget):
|
|||||||
self.imageItem.setPos(*pos)
|
self.imageItem.setPos(*pos)
|
||||||
if transform is not None:
|
if transform is not None:
|
||||||
self.imageItem.setTransform(transform)
|
self.imageItem.setTransform(transform)
|
||||||
prof.mark('6')
|
|
||||||
|
profiler()
|
||||||
|
|
||||||
if autoRange:
|
if autoRange:
|
||||||
self.autoRange()
|
self.autoRange()
|
||||||
self.roiClicked()
|
self.roiClicked()
|
||||||
prof.mark('7')
|
|
||||||
prof.finish()
|
|
||||||
|
|
||||||
|
profiler()
|
||||||
|
|
||||||
def play(self, rate):
|
def play(self, rate):
|
||||||
"""Begin automatically stepping frames forward at the given rate (in fps).
|
"""Begin automatically stepping frames forward at the given rate (in fps).
|
||||||
|
Loading…
Reference in New Issue
Block a user