From 6c142046828125b386e7f76c42da62bae1668ff6 Mon Sep 17 00:00:00 2001 From: Nils Nemitz Date: Thu, 19 Nov 2020 02:31:28 +0900 Subject: [PATCH] Fix set empty (#1446) * changes to setData and dataRect to handle setting empty data * simplified named argument check * tests for clearing PlotDataItem by setData() and setData([],[]), commented out vestigal xClean/yClean * removed last remains of xClean/yClean --- pyqtgraph/graphicsItems/PlotDataItem.py | 43 +++++++++---------- .../graphicsItems/tests/test_PlotDataItem.py | 14 +++++- 2 files changed, 33 insertions(+), 24 deletions(-) diff --git a/pyqtgraph/graphicsItems/PlotDataItem.py b/pyqtgraph/graphicsItems/PlotDataItem.py index 30f745d1..b583bc94 100644 --- a/pyqtgraph/graphicsItems/PlotDataItem.py +++ b/pyqtgraph/graphicsItems/PlotDataItem.py @@ -226,7 +226,6 @@ class PlotDataItem(GraphicsObject): return self.opts['fftMode'] = mode self.xDisp = self.yDisp = None - self.xClean = self.yClean = None self.updateItems() self.informViewBoundsChanged() @@ -235,7 +234,6 @@ class PlotDataItem(GraphicsObject): return self.opts['logMode'] = [xMode, yMode] self.xDisp = self.yDisp = None - self.xClean = self.yClean = None self.updateItems() self.informViewBoundsChanged() @@ -245,7 +243,6 @@ class PlotDataItem(GraphicsObject): return self.opts['derivativeMode'] = mode self.xDisp = self.yDisp = None - self.xClean = self.yClean = None self.updateItems() self.informViewBoundsChanged() @@ -254,7 +251,6 @@ class PlotDataItem(GraphicsObject): return self.opts['phasemapMode'] = mode self.xDisp = self.yDisp = None - self.xClean = self.yClean = None self.updateItems() self.informViewBoundsChanged() @@ -470,8 +466,12 @@ class PlotDataItem(GraphicsObject): if 'x' in kargs: x = kargs['x'] + if dataType(x) == 'MetaArray': + x = x.asarray() if 'y' in kargs: y = kargs['y'] + if dataType(y) == 'MetaArray': + y = y.asarray() profiler('interpret data') ## pull in all style arguments. @@ -506,23 +506,22 @@ class PlotDataItem(GraphicsObject): #self.opts[k] = kargs[k] #scatterArgs[v] = self.opts[k] - - if y is None: - self.updateItems() - profiler('update items') - return - if y is not None and x is None: - x = np.arange(len(y)) - - if not isinstance(x, np.ndarray): - x = np.array(x) - if not isinstance(y, np.ndarray): - y = np.array(y) - - self.xData = x.view(np.ndarray) ## one last check to make sure there are no MetaArrays getting by - self.yData = y.view(np.ndarray) + if y is None or len(y) == 0: # empty data is represented as None + self.yData = None + else: # actual data is represented by ndarray + if not isinstance(y, np.ndarray): + y = np.array(y) + self.yData = y.view(np.ndarray) + if x is None: + x = np.arange(len(y)) + + if x is None or len(x)==0: # empty data is represented as None + self.xData = None + else: # actual data is represented by ndarray + if not isinstance(x, np.ndarray): + x = np.array(x) + self.xData = x.view(np.ndarray) # one last check to make sure there are no MetaArrays getting by self._dataRect = None - self.xClean = self.yClean = None self.xDisp = None self.yDisp = None profiler('set data') @@ -683,6 +682,8 @@ class PlotDataItem(GraphicsObject): return self._dataRect if self.xData is None or self.yData is None: return None + if len(self.xData) == 0: # avoid crash if empty data is represented by [] instead of None + return None with warnings.catch_warnings(): # All-NaN data is handled by returning None; Explicit numpy warning is not needed. warnings.simplefilter("ignore") @@ -751,8 +752,6 @@ class PlotDataItem(GraphicsObject): #self.scatters = [] self.xData = None self.yData = None - #self.xClean = None - #self.yClean = None self.xDisp = None self.yDisp = None self._dataRect = None diff --git a/pyqtgraph/graphicsItems/tests/test_PlotDataItem.py b/pyqtgraph/graphicsItems/tests/test_PlotDataItem.py index 926b6098..d58db91e 100644 --- a/pyqtgraph/graphicsItems/tests/test_PlotDataItem.py +++ b/pyqtgraph/graphicsItems/tests/test_PlotDataItem.py @@ -42,6 +42,11 @@ def test_setData(): pdi.setData(x, y) assert len(pdi.xData) == 150 assert len(pdi.yData) == 150 + + #test clear by empty call + pdi.setData() + assert pdi.xData is None + assert pdi.yData is None #test dict of x, y list y += list(np.random.normal(size=50)) @@ -50,14 +55,19 @@ def test_setData(): assert len(pdi.xData) == 200 assert len(pdi.yData) == 200 + #test clear by zero length arrays call + pdi.setData([],[]) + assert pdi.xData is None + assert pdi.yData is None + def test_clear(): y = list(np.random.normal(size=100)) x = np.linspace(5, 10, 100) pdi = pg.PlotDataItem(x, y) pdi.clear() - assert pdi.xData == None - assert pdi.yData == None + assert pdi.xData is None + assert pdi.yData is None def test_clear_in_step_mode(): w = pg.PlotWidget()