Fix to accidentally disabled style updates in PlotDataItem (#1653)

* allowed style updates to once again update the style of curve and scatter plot, added tests

* tests interleave assign and assert to guard against delayed assignment

* > > > now 100% more camels < < <
This commit is contained in:
Nils Nemitz 2021-03-24 03:54:15 +09:00 committed by GitHub
parent bb5a179647
commit 954c7342dd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 51 additions and 21 deletions

View File

@ -242,7 +242,7 @@ class PlotDataItem(GraphicsObject):
return return
self.opts['fftMode'] = mode self.opts['fftMode'] = mode
self.xDisp = self.yDisp = None self.xDisp = self.yDisp = None
self.updateItems() self.updateItems(styleUpdate=False)
self.informViewBoundsChanged() self.informViewBoundsChanged()
def setLogMode(self, xMode, yMode): def setLogMode(self, xMode, yMode):
@ -260,7 +260,7 @@ class PlotDataItem(GraphicsObject):
return return
self.opts['logMode'] = [xMode, yMode] self.opts['logMode'] = [xMode, yMode]
self.xDisp = self.yDisp = None self.xDisp = self.yDisp = None
self.updateItems() self.updateItems(styleUpdate=False)
self.informViewBoundsChanged() self.informViewBoundsChanged()
@ -269,7 +269,7 @@ class PlotDataItem(GraphicsObject):
return return
self.opts['derivativeMode'] = mode self.opts['derivativeMode'] = mode
self.xDisp = self.yDisp = None self.xDisp = self.yDisp = None
self.updateItems() self.updateItems(styleUpdate=False)
self.informViewBoundsChanged() self.informViewBoundsChanged()
def setPhasemapMode(self, mode): def setPhasemapMode(self, mode):
@ -277,7 +277,7 @@ class PlotDataItem(GraphicsObject):
return return
self.opts['phasemapMode'] = mode self.opts['phasemapMode'] = mode
self.xDisp = self.yDisp = None self.xDisp = self.yDisp = None
self.updateItems() self.updateItems(styleUpdate=False)
self.informViewBoundsChanged() self.informViewBoundsChanged()
def setPointMode(self, mode): def setPointMode(self, mode):
@ -297,7 +297,7 @@ class PlotDataItem(GraphicsObject):
#for c in self.curves: #for c in self.curves:
#c.setPen(pen) #c.setPen(pen)
#self.update() #self.update()
self.updateItems() self.updateItems(styleUpdate=True)
def setShadowPen(self, *args, **kargs): def setShadowPen(self, *args, **kargs):
""" """
@ -312,14 +312,14 @@ class PlotDataItem(GraphicsObject):
#for c in self.curves: #for c in self.curves:
#c.setPen(pen) #c.setPen(pen)
#self.update() #self.update()
self.updateItems() self.updateItems(styleUpdate=True)
def setFillBrush(self, *args, **kargs): def setFillBrush(self, *args, **kargs):
brush = fn.mkBrush(*args, **kargs) brush = fn.mkBrush(*args, **kargs)
if self.opts['fillBrush'] == brush: if self.opts['fillBrush'] == brush:
return return
self.opts['fillBrush'] = brush self.opts['fillBrush'] = brush
self.updateItems() self.updateItems(styleUpdate=True)
def setBrush(self, *args, **kargs): def setBrush(self, *args, **kargs):
return self.setFillBrush(*args, **kargs) return self.setFillBrush(*args, **kargs)
@ -328,14 +328,14 @@ class PlotDataItem(GraphicsObject):
if self.opts['fillLevel'] == level: if self.opts['fillLevel'] == level:
return return
self.opts['fillLevel'] = level self.opts['fillLevel'] = level
self.updateItems() self.updateItems(styleUpdate=True)
def setSymbol(self, symbol): def setSymbol(self, symbol):
if self.opts['symbol'] == symbol: if self.opts['symbol'] == symbol:
return return
self.opts['symbol'] = symbol self.opts['symbol'] = symbol
#self.scatter.setSymbol(symbol) #self.scatter.setSymbol(symbol)
self.updateItems() self.updateItems(styleUpdate=True)
def setSymbolPen(self, *args, **kargs): def setSymbolPen(self, *args, **kargs):
pen = fn.mkPen(*args, **kargs) pen = fn.mkPen(*args, **kargs)
@ -343,7 +343,7 @@ class PlotDataItem(GraphicsObject):
return return
self.opts['symbolPen'] = pen self.opts['symbolPen'] = pen
#self.scatter.setSymbolPen(pen) #self.scatter.setSymbolPen(pen)
self.updateItems() self.updateItems(styleUpdate=True)
def setSymbolBrush(self, *args, **kargs): def setSymbolBrush(self, *args, **kargs):
brush = fn.mkBrush(*args, **kargs) brush = fn.mkBrush(*args, **kargs)
@ -351,7 +351,7 @@ class PlotDataItem(GraphicsObject):
return return
self.opts['symbolBrush'] = brush self.opts['symbolBrush'] = brush
#self.scatter.setSymbolBrush(brush) #self.scatter.setSymbolBrush(brush)
self.updateItems() self.updateItems(styleUpdate=True)
def setSymbolSize(self, size): def setSymbolSize(self, size):
@ -359,7 +359,7 @@ class PlotDataItem(GraphicsObject):
return return
self.opts['symbolSize'] = size self.opts['symbolSize'] = size
#self.scatter.setSymbolSize(symbolSize) #self.scatter.setSymbolSize(symbolSize)
self.updateItems() self.updateItems(styleUpdate=True)
def setDownsampling(self, ds=None, auto=None, method=None): def setDownsampling(self, ds=None, auto=None, method=None):
""" """
@ -396,14 +396,14 @@ class PlotDataItem(GraphicsObject):
if changed: if changed:
self.xDisp = self.yDisp = None self.xDisp = self.yDisp = None
self.updateItems() self.updateItems(styleUpdate=False)
def setClipToView(self, clip): def setClipToView(self, clip):
if self.opts['clipToView'] == clip: if self.opts['clipToView'] == clip:
return return
self.opts['clipToView'] = clip self.opts['clipToView'] = clip
self.xDisp = self.yDisp = None self.xDisp = self.yDisp = None
self.updateItems() self.updateItems(styleUpdate=False)
def setDynamicRangeLimit(self, limit=1e06, hysteresis=3.): def setDynamicRangeLimit(self, limit=1e06, hysteresis=3.):
""" """
@ -431,7 +431,7 @@ class PlotDataItem(GraphicsObject):
return # avoid update if there is no change return # avoid update if there is no change
self.opts['dynamicRangeLimit'] = limit # can be None self.opts['dynamicRangeLimit'] = limit # can be None
self.xDisp = self.yDisp = None self.xDisp = self.yDisp = None
self.updateItems() self.updateItems(styleUpdate=False)
def setData(self, *args, **kargs): def setData(self, *args, **kargs):
""" """
@ -575,7 +575,7 @@ class PlotDataItem(GraphicsObject):
self.yDisp = None self.yDisp = None
profiler('set data') profiler('set data')
self.updateItems( update_style = self._styleWasChanged ) self.updateItems( styleUpdate = self._styleWasChanged )
self._styleWasChanged = False # items have been updated self._styleWasChanged = False # items have been updated
profiler('update items') profiler('update items')
@ -587,10 +587,10 @@ class PlotDataItem(GraphicsObject):
self.sigPlotChanged.emit(self) self.sigPlotChanged.emit(self)
profiler('emit') profiler('emit')
def updateItems(self, update_style=False): def updateItems(self, styleUpdate=True):
curveArgs = {} curveArgs = {}
scatterArgs = {} scatterArgs = {}
if update_style: # 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')]:
if k in self.opts: if k in self.opts:
curveArgs[v] = self.opts[k] curveArgs[v] = self.opts[k]
@ -872,10 +872,10 @@ class PlotDataItem(GraphicsObject):
or self.opts['autoDownsample'] or self.opts['autoDownsample']
): ):
self.xDisp = self.yDisp = None self.xDisp = self.yDisp = None
self.updateItems() self.updateItems(styleUpdate=False)
elif self.opts['dynamicRangeLimit'] is not None: elif self.opts['dynamicRangeLimit'] is not None:
# do not discard cached display data # update, but do not discard cached display data
self.updateItems() self.updateItems(styleUpdate=False)
def _fourierTransform(self, x, y): def _fourierTransform(self, x, y):
## Perform fourier transform. If x values are not sampled uniformly, ## Perform fourier transform. If x values are not sampled uniformly,

View File

@ -1,5 +1,6 @@
import numpy as np import numpy as np
import pyqtgraph as pg import pyqtgraph as pg
from pyqtgraph.Qt import QtGui
pg.mkQApp() pg.mkQApp()
@ -60,6 +61,35 @@ def test_setData():
assert pdi.xData is None assert pdi.xData is None
assert pdi.yData is None assert pdi.yData is None
def test_opts():
# test that curve and scatter plot properties get updated from PlotDataItem methods
y = list(np.random.normal(size=100))
x = np.linspace(5, 10, 100)
pdi = pg.PlotDataItem(x, y)
pen = QtGui.QPen( QtGui.QColor('#FF0000') )
pen2 = QtGui.QPen( QtGui.QColor('#FFFF00') )
brush = QtGui.QBrush( QtGui.QColor('#00FF00'))
brush2 = QtGui.QBrush( QtGui.QColor('#00FFFF'))
float_value = 1.0 + 20*np.random.random()
pen2.setWidth( int(float_value) )
pdi.setPen(pen)
assert pdi.curve.opts['pen'] == pen
pdi.setShadowPen(pen2)
assert pdi.curve.opts['shadowPen'] == pen2
pdi.setFillLevel( float_value )
assert pdi.curve.opts['fillLevel'] == float_value
pdi.setFillBrush(brush2)
assert pdi.curve.opts['brush'] == brush2
pdi.setSymbol('t')
assert pdi.scatter.opts['symbol'] == 't'
pdi.setSymbolPen(pen)
assert pdi.scatter.opts['pen'] == pen
pdi.setSymbolBrush(brush)
assert pdi.scatter.opts['brush'] == brush
pdi.setSymbolSize( float_value )
assert pdi.scatter.opts['size'] == float_value
def test_clear(): def test_clear():
y = list(np.random.normal(size=100)) y = list(np.random.normal(size=100))
x = np.linspace(5, 10, 100) x = np.linspace(5, 10, 100)