diff --git a/examples/Plotting.py b/examples/Plotting.py index fc993b09..a41fcd1e 100644 --- a/examples/Plotting.py +++ b/examples/Plotting.py @@ -18,7 +18,7 @@ app = QtGui.QApplication([]) #mw.resize(800,800) win = pg.GraphicsWindow(title="Basic plotting examples") -win.resize(800,600) +win.resize(1000,600) diff --git a/graphicsItems/PlotCurveItem.py b/graphicsItems/PlotCurveItem.py index d267f58e..c49ce30b 100644 --- a/graphicsItems/PlotCurveItem.py +++ b/graphicsItems/PlotCurveItem.py @@ -6,6 +6,7 @@ from .GraphicsObject import GraphicsObject import pyqtgraph.functions as fn from pyqtgraph import debug from pyqtgraph.Point import Point +import pyqtgraph as pg import struct, sys __all__ = ['PlotCurveItem'] @@ -52,7 +53,6 @@ class PlotCurveItem(GraphicsObject): self.path = None self.fillPath = None self.exportOpts = False - self.antialias = False ## this is disastrous for performance. @@ -65,7 +65,8 @@ class PlotCurveItem(GraphicsObject): 'fillLevel': None, 'brush': None, 'stepMode': False, - 'name': None + 'name': None, + 'antialias': pg.getConfigOption('antialias'), } self.setClickable(kargs.get('clickable', False)) self.setData(*args, **kargs) @@ -168,7 +169,7 @@ class PlotCurveItem(GraphicsObject): def setData(self, *args, **kargs): """ - ============== ======================================================= + ============== ======================================================== **Arguments:** x, y (numpy arrays) Data to show pen Pen to use when drawing. Any single argument accepted by @@ -181,7 +182,9 @@ class PlotCurveItem(GraphicsObject): *fillLevel* brush QBrush to use when filling. Any single argument accepted by :func:`mkBrush ` is allowed. - ============== ======================================================= + antialias (bool) Whether to use antialiasing when drawing. This + is disabled by default because it decreases performance. + ============== ======================================================== If non-keyword arguments are used, they will be interpreted as setData(y) for a single argument and setData(x, y) for two @@ -250,6 +253,8 @@ class PlotCurveItem(GraphicsObject): self.setFillLevel(kargs['fillLevel']) if 'brush' in kargs: self.setBrush(kargs['brush']) + if 'antialias' in kargs: + self.opts['antialias'] = kargs['antialias'] prof.mark('set') @@ -398,6 +403,14 @@ class PlotCurveItem(GraphicsObject): path = self.path prof.mark('generate path') + + if self.exportOpts is not False: + aa = self.exportOpts['antialias'] + else: + aa = self.opts['antialias'] + + p.setRenderHint(p.Antialiasing, aa) + if self.opts['brush'] is not None and self.opts['fillLevel'] is not None: if self.fillPath is None: @@ -426,12 +439,6 @@ class PlotCurveItem(GraphicsObject): #pen.setColor(c) ##pen.setCosmetic(True) - if self.exportOpts is not False: - aa = self.exportOpts['antialias'] - else: - aa = self.antialias - - p.setRenderHint(p.Antialiasing, aa) if sp is not None: diff --git a/graphicsItems/PlotDataItem.py b/graphicsItems/PlotDataItem.py index 58158905..f3db53ba 100644 --- a/graphicsItems/PlotDataItem.py +++ b/graphicsItems/PlotDataItem.py @@ -7,6 +7,7 @@ import numpy as np import scipy import pyqtgraph.functions as fn import pyqtgraph.debug as debug +import pyqtgraph as pg class PlotDataItem(GraphicsObject): """ @@ -84,6 +85,9 @@ class PlotDataItem(GraphicsObject): **Optimization keyword arguments:** ========== ===================================================================== + antialias (bool) By default, antialiasing is disabled to improve performance. + Note that in some cases (in particluar, when pxMode=True), points + will be rendered antialiased even if this is set to False. identical *deprecated* decimate (int) sub-sample data by selecting every nth sample before plotting ========== ===================================================================== @@ -130,6 +134,7 @@ class PlotDataItem(GraphicsObject): 'symbolBrush': (50, 50, 150), 'pxMode': True, + 'antialias': pg.getConfigOption('antialias'), 'pointMode': None, 'data': None, @@ -379,11 +384,11 @@ class PlotDataItem(GraphicsObject): #c.scene().removeItem(c) curveArgs = {} - for k,v in [('pen','pen'), ('shadowPen','shadowPen'), ('fillLevel','fillLevel'), ('fillBrush', 'brush')]: + for k,v in [('pen','pen'), ('shadowPen','shadowPen'), ('fillLevel','fillLevel'), ('fillBrush', 'brush'), ('antialias', 'antialias')]: curveArgs[v] = self.opts[k] scatterArgs = {} - for k,v in [('symbolPen','pen'), ('symbolBrush','brush'), ('symbol','symbol'), ('symbolSize', 'size'), ('data', 'data'), ('pxMode', 'pxMode')]: + 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] diff --git a/graphicsItems/PlotItem/PlotItem.py b/graphicsItems/PlotItem/PlotItem.py index 8281f031..42ae1830 100644 --- a/graphicsItems/PlotItem/PlotItem.py +++ b/graphicsItems/PlotItem/PlotItem.py @@ -131,6 +131,9 @@ class PlotItem(GraphicsWidget): self.autoBtn = ButtonItem(pyqtgraph.pixmaps.getPixmap('auto'), 14, self) self.autoBtn.mode = 'auto' self.autoBtn.clicked.connect(self.autoBtnClicked) + #self.autoBtn.hide() + self.buttonsHidden = False ## whether the user has requested buttons to be hidden + self.mouseHovering = False self.layout = QtGui.QGraphicsGridLayout() self.layout.setContentsMargins(1,1,1,1) @@ -141,6 +144,7 @@ class PlotItem(GraphicsWidget): if viewBox is None: viewBox = ViewBox() self.vb = viewBox + self.vb.sigStateChanged.connect(self.viewStateChanged) self.setMenuEnabled(enableMenu, enableMenu) ## en/disable plotitem and viewbox menus if name is not None: @@ -476,9 +480,13 @@ class PlotItem(GraphicsWidget): def autoBtnClicked(self): if self.autoBtn.mode == 'auto': self.enableAutoRange() + self.autoBtn.hide() else: self.disableAutoRange() + def viewStateChanged(self): + self.updateButtons() + def enableAutoScale(self): """ Enable auto-scaling. The plot will continuously scale to fit the boundaries of its data. @@ -1003,7 +1011,14 @@ class PlotItem(GraphicsWidget): def menuEnabled(self): return self._menuEnabled - + def hoverEvent(self, ev): + if ev.enter: + self.mouseHovering = True + if ev.exit: + self.mouseHovering = False + + self.updateButtons() + def getLabel(self, key): pass @@ -1082,8 +1097,20 @@ class PlotItem(GraphicsWidget): def hideButtons(self): """Causes auto-scale button ('A' in lower-left corner) to be hidden for this PlotItem""" #self.ctrlBtn.hide() - self.autoBtn.hide() + self.buttonsHidden = True + self.updateButtons() + def showButtons(self): + """Causes auto-scale button ('A' in lower-left corner) to be visible for this PlotItem""" + #self.ctrlBtn.hide() + self.buttonsHidden = False + self.updateButtons() + + def updateButtons(self): + if self.mouseHovering and not self.buttonsHidden and not all(self.vb.autoRangeEnabled()): + self.autoBtn.show() + else: + self.autoBtn.hide() def _plotArray(self, arr, x=None, **kargs): if arr.ndim != 1: diff --git a/graphicsItems/ScatterPlotItem.py b/graphicsItems/ScatterPlotItem.py index 155330f1..2528d35b 100644 --- a/graphicsItems/ScatterPlotItem.py +++ b/graphicsItems/ScatterPlotItem.py @@ -8,6 +8,7 @@ import scipy.stats import weakref import pyqtgraph.debug as debug from pyqtgraph.pgcollections import OrderedDict +import pyqtgraph as pg #import pyqtgraph as pg __all__ = ['ScatterPlotItem', 'SpotItem'] @@ -233,7 +234,12 @@ class ScatterPlotItem(GraphicsObject): self.bounds = [None, None] ## caches data bounds self._maxSpotWidth = 0 ## maximum size of the scale-variant portion of all spots self._maxSpotPxWidth = 0 ## maximum size of the scale-invariant portion of all spots - self.opts = {'pxMode': True, 'useCache': True, 'exportMode': False} ## If useCache is False, symbols are re-drawn on every paint. + self.opts = { + 'pxMode': True, + 'useCache': True, ## If useCache is False, symbols are re-drawn on every paint. + 'antialias': pg.getConfigOption('antialias'), + } + self.exportOpts = False self.setPen(200,200,200, update=False) self.setBrush(100,100,150, update=False) @@ -278,6 +284,9 @@ class ScatterPlotItem(GraphicsObject): it is in the item's local coordinate system. *data* a list of python objects used to uniquely identify each spot. *identical* *Deprecated*. This functionality is handled automatically now. + *antialias* Whether to draw symbols with antialiasing. Note that if pxMode is True, symbols are + always rendered with antialiasing (since the rendered symbols can be cached, this + incurs very little performance cost) ====================== =============================================================================================== """ oldData = self.data ## this causes cached pixmaps to be preserved while new data is registered. @@ -369,6 +378,8 @@ class ScatterPlotItem(GraphicsObject): if 'pxMode' in kargs: self.setPxMode(kargs['pxMode']) + if 'antialias' in kargs: + self.opts['antialias'] = kargs['antialias'] ## Set any extra parameters provided in keyword arguments for k in ['pen', 'brush', 'symbol', 'size']: @@ -378,7 +389,7 @@ class ScatterPlotItem(GraphicsObject): if 'data' in kargs: self.setPointData(kargs['data'], dataSet=newData) - + self.prepareGeometryChange() self.bounds = [None, None] self.invalidate() @@ -664,8 +675,13 @@ class ScatterPlotItem(GraphicsObject): rect = QtCore.QRectF(y, x, h, w) self.fragments.append(QtGui.QPainter.PixmapFragment.create(pos, rect)) - def setExportMode(self, enabled, opts): - self.opts['exportMode'] = enabled + def setExportMode(self, export, opts): + if export: + self.exportOpts = opts + if 'antialias' not in opts: + self.exportOpts['antialias'] = True + else: + self.exportOpts = False def paint(self, p, *args): @@ -685,9 +701,15 @@ class ScatterPlotItem(GraphicsObject): p.resetTransform() - if not USE_PYSIDE and self.opts['useCache'] and self.opts['exportMode'] is False: + if not USE_PYSIDE and self.opts['useCache'] and self.exportOpts is False: p.drawPixmapFragments(self.fragments, atlas) else: + if self.exportOpts is not False: + aa = self.exportOpts['antialias'] + else: + aa = self.opts['antialias'] + p.setRenderHint(p.Antialiasing, aa) + for i in range(len(self.data)): rec = self.data[i] frag = self.fragments[i] @@ -705,6 +727,11 @@ class ScatterPlotItem(GraphicsObject): drawSymbol(p2, *self.getSpotOpts(rec)) p2.end() + if self.exportOpts is not False: + aa = self.exportOpts['antialias'] + else: + aa = self.opts['antialias'] + p.setRenderHint(p.Antialiasing, aa) self.picture.play(p)