Repository: pyqtgraph/pyqtgraph

Issue:
Plot option `maxTraces` is doing the opposite of what it's supposed to do
### Short description
`maxTraces` plot option is hiding the most recent `n` lines, rather than only showing them.

### Code to reproduce
```python
import pyqtgraph as pg
import numpy as np

p = pg.plot()
p.plotItem.ctrl.maxTracesCheck.setChecked(True)
p.plotItem.ctrl.maxTracesSpin.setValue(3)

for i in range(10):
    p.plot(np.random.normal(size=100) + i*10)
```

### Expected behavior
The plot should only show the 3 top-most lines.

### Real behavior
The plot shows only the 7 bottom-most lines.

### Tested environment(s)

 * PyQtGraph version: master
 * Qt Python binding: PyQt5 5.12.3
 * Python version: 3.7.10
 * NumPy version: 1.20.2
 * Operating system: linux, windows
 * Installation method: conda + git

### Additional Context
This behavior is the same when the option is controlled through the plot's menu interface. Hopefully I'll get around to fixing this presently.


Discussion:
Oh, this behaves worse than I thought. _No_ lines are showing up in the plot with this option enabled. I tried to reproduce the effect of the user interface (which is what the bug describes), but huh. Oh well, the script still reproduces _something_.

Also, I just bisected to https://github.com/pyqtgraph/pyqtgraph/commit/b7b431de8d31c1d894ffc368ff5cd562fcc13678, with something else weird happening at https://github.com/pyqtgraph/pyqtgraph/commit/d77ad273c71870881c3fda3d2b49d3488f100425.

Resolving patch:
diff --git a/pyqtgraph/graphicsItems/PlotItem/PlotItem.py b/pyqtgraph/graphicsItems/PlotItem/PlotItem.py
--- a/pyqtgraph/graphicsItems/PlotItem/PlotItem.py
+++ b/pyqtgraph/graphicsItems/PlotItem/PlotItem.py
@@ -1003,20 +1003,19 @@ def clipToViewMode(self):
         return self.ctrl.clipToViewCheck.isChecked()
 
     def updateDecimation(self):
-        if self.ctrl.maxTracesCheck.isChecked():
-            numCurves = self.ctrl.maxTracesSpin.value()
+        if not self.ctrl.maxTracesCheck.isChecked():
+            numCurves = len(self.curves)
         else:
-            numCurves = -1
-            
-        curves = self.curves[:]
-        split = len(curves) - numCurves
-        for curve in curves[split:]:
-            if numCurves != -1:
-                if self.ctrl.forgetTracesCheck.isChecked():
-                    curve.clear()
-                    self.removeItem(curve)
-                else:
-                    curve.hide()        
+            numCurves = self.ctrl.maxTracesSpin.value()
+
+        for i, curve in enumerate(self.curves):
+            if i < numCurves:
+                curve.show()
+            elif self.ctrl.forgetTracesCheck.isChecked():
+                curve.clear()
+                self.removeItem(curve)
+            else:
+                curve.hide()
       
     def updateAlpha(self, *args):
         (alpha, auto) = self.alphaState()


Test patch:
diff --git a/pyqtgraph/graphicsItems/PlotItem/tests/test_PlotItem.py b/pyqtgraph/graphicsItems/PlotItem/tests/test_PlotItem.py
--- a/pyqtgraph/graphicsItems/PlotItem/tests/test_PlotItem.py
+++ b/pyqtgraph/graphicsItems/PlotItem/tests/test_PlotItem.py
@@ -1,5 +1,7 @@
 # -*- coding: utf-8 -*-
+import numpy as np
 import pytest
+
 import pyqtgraph as pg
 
 app = pg.mkQApp()
@@ -23,6 +25,21 @@ def test_PlotItem_shared_axis_items(orientation):
         pi2.setAxisItems({orientation: ax1})
 
 
+def test_PlotItem_maxTraces():
+    item = pg.PlotItem()
+
+    curve1 = pg.PlotDataItem(np.random.normal(size=10))
+    item.addItem(curve1)
+    assert curve1.isVisible(), f"{curve1} should be visible"
+
+    item.ctrl.maxTracesCheck.setChecked(True)
+    item.ctrl.maxTracesSpin.setValue(0)
+    assert not curve1.isVisible(), f"{curve1} should not be visible"
+
+    item.ctrl.maxTracesCheck.setChecked(False)
+    assert curve1.isVisible(), f"{curve1} should be visible"
+
+
 def test_plotitem_menu_initialize():
     """Test the menu initialization of the plotitem"""
     item = pg.PlotItem()