Clean ScatterPlotItem

This commit is contained in:
Guillaume Poulin 2013-09-24 17:06:51 +08:00
parent 73a079a649
commit 36979b67ea

View File

@ -687,35 +687,40 @@ class ScatterPlotItem(GraphicsObject):
self.fragments = None self.fragments = None
self.target = None self.target = None
def generateFragments(self): def setExportMode(self, *args, **kwds):
GraphicsObject.setExportMode(self, *args, **kwds)
self.invalidate()
def getTransformedPoint(self):
tr = self.deviceTransform() tr = self.deviceTransform()
if tr is None: if tr is None:
return return None, None
mask = np.logical_and( ## Remove out of view points
np.logical_and(self.data['x'] - self.data['width'] > range[0][0], w = np.empty((2,len(self.data['width'])))
self.data['x'] + self.data['width'] < range[0][1]), w[0] = self.data['width']
np.logical_and(self.data['y'] - self.data['width'] > range[1][0], w[1] = self.data['width']
self.data['y'] + self.data['width'] < range[1][1])) ## remove out of view points q, intv = tr.inverted()
data = self.data[mask] if intv:
w = fn.transformCoordinates(q, w)
w=np.abs(w)
range = self.getViewBox().viewRange()
mask = np.logical_and(
np.logical_and(self.data['x'] + w[0,:] > range[0][0],
self.data['x'] - w[0,:] < range[0][1]),
np.logical_and(self.data['y'] + w[0,:] > range[1][0],
self.data['y'] - w[0,:] < range[1][1])) ## remove out of view points
data = self.data[mask]
else:
data = self.data
pts = np.empty((2,len(data['x']))) pts = np.empty((2,len(data['x'])))
pts[0] = data['x'] pts[0] = data['x']
pts[1] = data['y'] pts[1] = data['y']
pts = fn.transformCoordinates(tr, pts) pts = fn.transformCoordinates(tr, pts)
self.fragments = [] pts -= data['width']
pts = np.clip(pts, -2**30, 2**30) ## prevent Qt segmentation fault. pts = np.clip(pts, -2**30, 2**30)
## Still won't be able to render correctly, though. return data, pts
#for i in xrange(len(self.data)):
# rec = self.data[i]
# pos = QtCore.QPointF(pts[0,i], pts[1,i])
# x,y,w,h = rec['fragCoords']
# rect = QtCore.QRectF(y, x, h, w)
# self.fragments.append(QtGui.QPainter.PixmapFragment.create(pos, rect))
pos = imap(QtCore.QPointF, pts[0,:], pts[1,:])
self.fragments = list(imap(QtGui.QPainter.PixmapFragment.create, pos, self.data['rectSrc']))
def setExportMode(self, *args, **kwds):
GraphicsObject.setExportMode(self, *args, **kwds)
self.invalidate()
@pg.debug.warnOnException ## raising an exception here causes crash @pg.debug.warnOnException ## raising an exception here causes crash
def paint(self, p, *args): def paint(self, p, *args):
@ -732,44 +737,14 @@ class ScatterPlotItem(GraphicsObject):
if self.opts['pxMode'] is True: if self.opts['pxMode'] is True:
atlas = self.fragmentAtlas.getAtlas() atlas = self.fragmentAtlas.getAtlas()
#arr = fn.imageToArray(atlas.toImage(), copy=True)
#if hasattr(self, 'lastAtlas'):
#if np.any(self.lastAtlas != arr):
#print "Atlas changed:", arr
#self.lastAtlas = arr
#if self.fragments is None:
#self.updateSpots()
#self.generateFragments()
p.resetTransform() p.resetTransform()
data, pts = self.getTransformedPoint()
if data is None:
return
if self.opts['useCache'] and self._exportOpts is False: if self.opts['useCache'] and self._exportOpts is False:
tr = self.deviceTransform()
if tr is None:
return
w = np.empty((2,len(self.data['width'])))
w[0] = self.data['width']
w[1] = self.data['width']
q, intv = tr.inverted()
if intv:
w = fn.transformCoordinates(q, w)
w=np.abs(w)
range = self.getViewBox().viewRange()
mask = np.logical_and(
np.logical_and(self.data['x'] + w[0,:] > range[0][0],
self.data['x'] - w[0,:] < range[0][1]),
np.logical_and(self.data['y'] + w[0,:] > range[1][0],
self.data['y'] - w[0,:] < range[1][1])) ## remove out of view points
data = self.data[mask]
else:
data = self.data
pts = np.empty((2,len(data['x'])))
pts[0] = data['x']
pts[1] = data['y']
pts = fn.transformCoordinates(tr, pts)
pts -= data['width']
pts = np.clip(pts, -2**30, 2**30)
if self.target == None: if self.target == None:
list(imap(QtCore.QRectF.moveTo, data['rectTarg'], pts[0,:], pts[1,:])) list(imap(QtCore.QRectF.moveTo, data['rectTarg'], pts[0,:], pts[1,:]))
self.target=data['rectTarg'] self.target=data['rectTarg']
@ -777,17 +752,13 @@ class ScatterPlotItem(GraphicsObject):
list(imap(p.drawPixmap, self.target, repeat(atlas), data['rectSrc'])) list(imap(p.drawPixmap, self.target, repeat(atlas), data['rectSrc']))
else: else:
p.drawPixmapFragments(self.target.tolist(), data['rectSrc'].tolist(), atlas) p.drawPixmapFragments(self.target.tolist(), data['rectSrc'].tolist(), atlas)
#p.drawPixmapFragments(self.fragments, atlas)
else: else:
if self.fragments is None:
self.generateFragments()
p.setRenderHint(p.Antialiasing, aa) p.setRenderHint(p.Antialiasing, aa)
for i in range(len(self.data)): for i in range(len(self.data)):
rec = self.data[i] rec = data[i]
frag = self.fragments[i]
p.resetTransform() p.resetTransform()
p.translate(frag.x, frag.y) p.translate(pts[0,i], pts[1,i])
drawSymbol(p, *self.getSpotOpts(rec, scale)) drawSymbol(p, *self.getSpotOpts(rec, scale))
else: else:
if self.picture is None: if self.picture is None:
@ -798,7 +769,7 @@ class ScatterPlotItem(GraphicsObject):
rec = rec.copy() rec = rec.copy()
rec['size'] *= scale rec['size'] *= scale
p2.resetTransform() p2.resetTransform()
p2.translate(rec['x'], rec['y']) p2.translate(rec['x']+rec['width'], rec['y']+rec['width'])
drawSymbol(p2, *self.getSpotOpts(rec, scale)) drawSymbol(p2, *self.getSpotOpts(rec, scale))
p2.end() p2.end()