Repository: spyder-ide/spyder

Issue:
When plotting new plot, plot pane does automatically scroll down to newest plot.

I'm using 4.0.0rc3. 

The plot displays the last made plot, but the scroll bar on the right does not default to its lowest scroll point. Not a huge deal, just notifying the Spyder team that I'm seeing it!

Also, I LOVE the new update from 3.6 -> 4.0!! Great work! 




Discussion:

Resolving patch:
diff --git a/spyder/plugins/plots/widgets/figurebrowser.py b/spyder/plugins/plots/widgets/figurebrowser.py
--- a/spyder/plugins/plots/widgets/figurebrowser.py
+++ b/spyder/plugins/plots/widgets/figurebrowser.py
@@ -581,11 +581,24 @@ class ThumbnailScrollBar(QFrame):
     def __init__(self, figure_viewer, parent=None, background_color=None):
         super(ThumbnailScrollBar, self).__init__(parent)
         self._thumbnails = []
+
         self.background_color = background_color
         self.current_thumbnail = None
         self.set_figureviewer(figure_viewer)
         self.setup_gui()
 
+        # Because the range of Qt scrollareas is not updated immediately
+        # after a new item is added to it, setting the scrollbar's value
+        # to its maximum value after adding a new item will scroll down to
+        # the penultimate item instead of the last.
+        # So to scroll programmatically to the latest item after it
+        # is added to the scrollarea, we need to do it instead in a slot
+        # connected to the scrollbar's rangeChanged signal.
+        # See spyder-ide/#10914 for more details.
+        self._new_thumbnail_added = False
+        self.scrollarea.verticalScrollBar().rangeChanged.connect(
+            self._scroll_to_newest_item)
+
     def setup_gui(self):
         """Setup the main layout of the widget."""
         scrollarea = self.setup_scrollarea()
@@ -604,6 +617,7 @@ def setup_scrollarea(self):
 
         self.scene = QGridLayout(self.view)
         self.scene.setContentsMargins(0, 0, 0, 0)
+        self.scene.setSpacing(3)
 
         self.scrollarea = QScrollArea()
         self.scrollarea.setWidget(self.view)
@@ -765,6 +779,7 @@ def add_thumbnail(self, fig, fmt):
         thumbnail.sig_remove_figure.connect(self.remove_thumbnail)
         thumbnail.sig_save_figure.connect(self.save_figure_as)
         self._thumbnails.append(thumbnail)
+        self._new_thumbnail_added = True
 
         self.scene.setRowStretch(self.scene.rowCount() - 1, 0)
         self.scene.addWidget(thumbnail, self.scene.rowCount() - 1, 0)
@@ -863,6 +878,17 @@ def scroll_to_item(self, index):
         vsb = self.scrollarea.verticalScrollBar()
         vsb.setValue(pos_scroll)
 
+    def _scroll_to_newest_item(self, vsb_min, vsb_max):
+        """
+        Scroll to the newest item added to the thumbnail scrollbar.
+
+        Note that this method is called each time the rangeChanged signal
+        is emitted by the scrollbar.
+        """
+        if self._new_thumbnail_added:
+            self._new_thumbnail_added = False
+            self.scrollarea.verticalScrollBar().setValue(vsb_max)
+
     # ---- ScrollBar Handlers
     def go_up(self):
         """Scroll the scrollbar of the scrollarea up by a single step."""


Test patch:
diff --git a/spyder/plugins/plots/widgets/tests/test_plots_widgets.py b/spyder/plugins/plots/widgets/tests/test_plots_widgets.py
--- a/spyder/plugins/plots/widgets/tests/test_plots_widgets.py
+++ b/spyder/plugins/plots/widgets/tests/test_plots_widgets.py
@@ -278,6 +278,34 @@ def test_scroll_to_item(figbrowser, tmpdir, qtbot):
     assert vsb.value() == expected
 
 
+def test_scroll_down_to_newest_plot(figbrowser, tmpdir, qtbot):
+    """
+    Test that the ThumbnailScrollBar is scrolled to the newest plot after
+    it is added to it.
+
+    Test that covers spyder-ide/spyder#10914.
+    """
+    figbrowser.setFixedSize(500, 500)
+
+    nfig = 8
+    for i in range(8):
+        newfig = create_figure(
+            osp.join(to_text_string(tmpdir), 'new_mplfig{}.png'.format(i)))
+        figbrowser._handle_new_figure(newfig, 'image/png')
+        qtbot.wait(500)
+
+    # Assert that the scrollbar range was updated correctly and that it's
+    # value was set to its maximum.
+    height_view = figbrowser.thumbnails_sb.scrollarea.viewport().height()
+    scene = figbrowser.thumbnails_sb.scene
+    spacing = scene.verticalSpacing()
+    height = scene.itemAt(0).sizeHint().height()
+
+    expected = (spacing * (nfig - 1)) + (height * nfig) - height_view
+    vsb = figbrowser.thumbnails_sb.scrollarea.verticalScrollBar()
+    assert vsb.value() == expected
+
+
 @pytest.mark.parametrize("fmt", ['image/png', 'image/svg+xml'])
 def test_mouse_clicking_thumbnails(figbrowser, tmpdir, qtbot, fmt):
     """