diff --git a/pyqtgraph/__init__.py b/pyqtgraph/__init__.py index 12a4f90f..c6b411a1 100644 --- a/pyqtgraph/__init__.py +++ b/pyqtgraph/__init__.py @@ -48,8 +48,8 @@ else: CONFIG_OPTIONS = { 'useOpenGL': useOpenGL, ## by default, this is platform-dependent (see widgets/GraphicsView). Set to True or False to explicitly enable/disable opengl. 'leftButtonPan': True, ## if false, left button drags a rubber band for zooming in viewbox - 'foreground': (150, 150, 150), ## default foreground color for axes, labels, etc. - 'background': (0, 0, 0), ## default background for GraphicsWidget + 'foreground': 'd', ## default foreground color for axes, labels, etc. + 'background': 'k', ## default background for GraphicsWidget 'antialias': False, 'editorCommand': None, ## command used to invoke code editor from ConsoleWidgets 'useWeave': True, ## Use weave to speed up some operations, if it is available diff --git a/pyqtgraph/functions.py b/pyqtgraph/functions.py index 14e4e076..33069d23 100644 --- a/pyqtgraph/functions.py +++ b/pyqtgraph/functions.py @@ -7,15 +7,19 @@ Distributed under MIT/X11 license. See license.txt for more infomation. from __future__ import division from .python2_3 import asUnicode +from .Qt import QtGui, QtCore, USE_PYSIDE Colors = { - 'b': (0,0,255,255), - 'g': (0,255,0,255), - 'r': (255,0,0,255), - 'c': (0,255,255,255), - 'm': (255,0,255,255), - 'y': (255,255,0,255), - 'k': (0,0,0,255), - 'w': (255,255,255,255), + 'b': QtGui.QColor(0,0,255,255), + 'g': QtGui.QColor(0,255,0,255), + 'r': QtGui.QColor(255,0,0,255), + 'c': QtGui.QColor(0,255,255,255), + 'm': QtGui.QColor(255,0,255,255), + 'y': QtGui.QColor(255,255,0,255), + 'k': QtGui.QColor(0,0,0,255), + 'w': QtGui.QColor(255,255,255,255), + 'd': QtGui.QColor(150,150,150,255), + 'l': QtGui.QColor(200,200,200,255), + 's': QtGui.QColor(100,100,150,255), } SI_PREFIXES = asUnicode('yzafpnµm kMGTPEZY') @@ -23,7 +27,6 @@ SI_PREFIXES_ASCII = 'yzafpnum kMGTPEZY' -from .Qt import QtGui, QtCore, USE_PYSIDE import pyqtgraph as pg import numpy as np import decimal, re @@ -169,17 +172,15 @@ def mkColor(*args): """ err = 'Not sure how to make a color from "%s"' % str(args) if len(args) == 1: - if isinstance(args[0], QtGui.QColor): - return QtGui.QColor(args[0]) - elif isinstance(args[0], float): - r = g = b = int(args[0] * 255) - a = 255 - elif isinstance(args[0], basestring): + if isinstance(args[0], basestring): c = args[0] if c[0] == '#': c = c[1:] if len(c) == 1: - (r, g, b, a) = Colors[c] + try: + return Colors[c] + except KeyError: + raise Exception(err) if len(c) == 3: r = int(c[0]*2, 16) g = int(c[1]*2, 16) @@ -200,6 +201,11 @@ def mkColor(*args): g = int(c[2:4], 16) b = int(c[4:6], 16) a = int(c[6:8], 16) + elif isinstance(args[0], QtGui.QColor): + return QtGui.QColor(args[0]) + elif isinstance(args[0], float): + r = g = b = int(args[0] * 255) + a = 255 elif hasattr(args[0], '__len__'): if len(args[0]) == 3: (r, g, b) = args[0] @@ -283,7 +289,7 @@ def mkPen(*args, **kargs): color = args if color is None: - color = mkColor(200, 200, 200) + color = mkColor('l') if hsv is not None: color = hsvColor(*hsv) else: diff --git a/pyqtgraph/graphicsItems/AxisItem.py b/pyqtgraph/graphicsItems/AxisItem.py index d82f5d41..3f2f6fcd 100644 --- a/pyqtgraph/graphicsItems/AxisItem.py +++ b/pyqtgraph/graphicsItems/AxisItem.py @@ -266,8 +266,7 @@ class AxisItem(GraphicsWidget): self.picture = None def pen(self): - if self._pen is None: - return fn.mkPen(pg.getConfigOption('foreground')) + #return self._pen return pg.mkPen(self._pen) def setPen(self, pen): @@ -276,11 +275,11 @@ class AxisItem(GraphicsWidget): if pen == None, the default will be used (see :func:`setConfigOption `) """ - self._pen = pen self.picture = None if pen is None: pen = pg.getConfigOption('foreground') - self.labelStyle['color'] = '#' + pg.colorStr(pg.mkPen(pen).color())[:6] + self._pen = pg.mkPen(pen) + self.labelStyle['color'] = '#' + pg.colorStr(self._pen.color())[:6] self.setLabel() self.update() diff --git a/pyqtgraph/graphicsItems/ScatterPlotItem.py b/pyqtgraph/graphicsItems/ScatterPlotItem.py index 97f5aa8f..3cab5ffe 100644 --- a/pyqtgraph/graphicsItems/ScatterPlotItem.py +++ b/pyqtgraph/graphicsItems/ScatterPlotItem.py @@ -98,31 +98,41 @@ class SymbolAtlas(object): # weak value; if all external refs to this list disappear, # the symbol will be forgotten. self.symbolMap = weakref.WeakValueDictionary() + self.symbolPen = weakref.WeakValueDictionary() + self.symbolBrush = weakref.WeakValueDictionary() self.atlasData = None # numpy array of atlas image self.atlas = None # atlas as QPixmap self.atlasValid = False + self.max_width=0 def getSymbolCoords(self, opts): """ Given a list of spot records, return an object representing the coordinates of that symbol within the atlas """ coords = np.empty(len(opts), dtype=object) + keyi = None + coordi = None for i, rec in enumerate(opts): - symbol, size, pen, brush = rec['symbol'], rec['size'], rec['pen'], rec['brush'] - pen = fn.mkPen(pen) if not isinstance(pen, QtGui.QPen) else pen - brush = fn.mkBrush(brush) if not isinstance(pen, QtGui.QBrush) else brush - key = (symbol, size, fn.colorTuple(pen.color()), pen.widthF(), pen.style(), fn.colorTuple(brush.color())) - if key not in self.symbolMap: - newCoords = SymbolAtlas.SymbolCoords() - self.symbolMap[key] = newCoords - self.atlasValid = False - #try: - #self.addToAtlas(key) ## squeeze this into the atlas if there is room - #except: - #self.buildAtlas() ## otherwise, we need to rebuild - - coords[i] = self.symbolMap[key] + key = (rec[3], rec[2], id(rec[4]), id(rec[5])) + if key == keyi: + coords[i]=coordi + else: + try: + coords[i] = self.symbolMap[key] + except KeyError: + newCoords = SymbolAtlas.SymbolCoords() + self.symbolMap[key] = newCoords + self.symbolPen[key] = rec['pen'] + self.symbolBrush[key] = rec['brush'] + self.atlasValid = False + #try: + #self.addToAtlas(key) ## squeeze this into the atlas if there is room + #except: + #self.buildAtlas() ## otherwise, we need to rebuild + coords[i] = newCoords + keyi = key + coordi = newCoords return coords def buildAtlas(self): @@ -133,8 +143,8 @@ class SymbolAtlas(object): images = [] for key, coords in self.symbolMap.items(): if len(coords) == 0: - pen = fn.mkPen(color=key[2], width=key[3], style=key[4]) - brush = fn.mkBrush(color=key[5]) + pen = self.symbolPen[key] + brush = self.symbolBrush[key] img = renderSymbol(key[0], key[1], pen, brush) images.append(img) ## we only need this to prevent the images being garbage collected immediately arr = fn.imageToArray(img, copy=False, transpose=False) @@ -181,6 +191,7 @@ class SymbolAtlas(object): self.atlasData[x:x+w, y:y+h] = rendered[key] self.atlas = None self.atlasValid = True + self.max_width=maxWidth def getAtlas(self): if not self.atlasValid: @@ -237,8 +248,8 @@ class ScatterPlotItem(GraphicsObject): 'antialias': pg.getConfigOption('antialias'), } - self.setPen(200,200,200, update=False) - self.setBrush(100,100,150, update=False) + self.setPen('l', update=False) + self.setBrush('s', update=False) self.setSymbol('o', update=False) self.setSize(7, update=False) prof.mark('1') @@ -533,10 +544,8 @@ class ScatterPlotItem(GraphicsObject): def updateSpots(self, dataSet=None): if dataSet is None: dataSet = self.data - self._maxSpotWidth = 0 - self._maxSpotPxWidth = 0 + invalidate = False - self.measureSpotSizes(dataSet) if self.opts['pxMode']: mask = np.equal(dataSet['fragCoords'], None) if np.any(mask): @@ -549,6 +558,13 @@ class ScatterPlotItem(GraphicsObject): #if rec['fragCoords'] is None: #invalidate = True #rec['fragCoords'] = self.fragmentAtlas.getSymbolCoords(*self.getSpotOpts(rec)) + self.fragmentAtlas.getAtlas() + self._maxSpotPxWidth=self.fragmentAtlas.max_width + else: + self._maxSpotWidth = 0 + self._maxSpotPxWidth = 0 + self.measureSpotSizes(dataSet) + if invalidate: self.invalidate() @@ -666,7 +682,7 @@ class ScatterPlotItem(GraphicsObject): GraphicsObject.viewTransformChanged(self) self.bounds = [None, None] self.fragments = None - + def generateFragments(self): tr = self.deviceTransform() if tr is None: @@ -711,7 +727,7 @@ class ScatterPlotItem(GraphicsObject): #self.lastAtlas = arr if self.fragments is None: - self.updateSpots() + #self.updateSpots() self.generateFragments() p.resetTransform()