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.
in d77ad27 those extra calls to `updateMatrix` really had some nasty side effects... 

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
@@ -238,6 +238,7 @@ def __init__(self, parent=None, name=None, labels=None, title=None, viewBox=None
         self.ctrl.averageGroup.toggled.connect(self.avgToggled)
         
         self.ctrl.maxTracesCheck.toggled.connect(self.updateDecimation)
+        self.ctrl.forgetTracesCheck.toggled.connect(self.updateDecimation)
         self.ctrl.maxTracesSpin.valueChanged.connect(self.updateDecimation)
         
         if labels is None:
@@ -1008,12 +1009,14 @@ def updateDecimation(self):
         else:
             numCurves = self.ctrl.maxTracesSpin.value()
 
-        for i, curve in enumerate(self.curves):
-            if i < numCurves:
-                curve.show()
-            elif self.ctrl.forgetTracesCheck.isChecked():
+        if self.ctrl.forgetTracesCheck.isChecked():
+            for curve in self.curves[:-numCurves]:
                 curve.clear()
                 self.removeItem(curve)
+
+        for i, curve in enumerate(reversed(self.curves)):
+            if i < numCurves:
+                curve.show()
             else:
                 curve.hide()
       


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
@@ -30,14 +30,28 @@ def test_PlotItem_maxTraces():
 
     curve1 = pg.PlotDataItem(np.random.normal(size=10))
     item.addItem(curve1)
-    assert curve1.isVisible(), f"{curve1} should be visible"
+    assert curve1.isVisible(), "curve1 should be visible"
 
     item.ctrl.maxTracesCheck.setChecked(True)
     item.ctrl.maxTracesSpin.setValue(0)
-    assert not curve1.isVisible(), f"{curve1} should not be visible"
+    assert not curve1.isVisible(), "curve1 should not be visible"
 
     item.ctrl.maxTracesCheck.setChecked(False)
-    assert curve1.isVisible(), f"{curve1} should be visible"
+    assert curve1.isVisible(), "curve1 should be visible"
+
+    curve2 = pg.PlotDataItem(np.random.normal(size=10))
+    item.addItem(curve2)
+    assert curve2.isVisible(), "curve2 should be visible"
+
+    item.ctrl.maxTracesCheck.setChecked(True)
+    item.ctrl.maxTracesSpin.setValue(1)
+    assert curve2.isVisible(), "curve2 should be visible"
+    assert not curve1.isVisible(), "curve1 should not be visible"
+    assert curve1 in item.curves, "curve1 should be in the item's curves"
+
+    item.ctrl.forgetTracesCheck.setChecked(True)
+    assert curve2 in item.curves, "curve2 should be in the item's curves"
+    assert curve1 not in item.curves, "curve1 should not be in the item's curves"
 
 
 def test_plotitem_menu_initialize():