Exemple #1
0
def _run_apply_properties_on_figure_with_image():
    img_fig = figure()
    img_ax = img_fig.add_subplot(111)
    img_ax.imshow([[0, 1], [0, 1]], label='old label')
    presenter = PlotConfigDialogPresenter(img_fig, view=Mock())
    with patch.object(presenter.tab_widget_presenters[1], 'update_view',
                      lambda: None):
        presenter.apply_properties()
    return img_ax
Exemple #2
0
def _run_apply_properties_on_figure_with_curve():
    fig = figure()
    ax = fig.add_subplot(111)
    ax.errorbar([0, 1], [0, 1], yerr=[0.1, 0.2], label='old label')
    presenter = PlotConfigDialogPresenter(fig, view=Mock())
    with patch.object(presenter.tab_widget_presenters[1], 'update_view',
                      lambda: None):
        presenter.apply_properties()
    return ax
    def test_success_callback(self):
        fig = figure()
        fig.canvas.draw = Mock()
        mock_view = Mock()
        presenter = PlotConfigDialogPresenter(fig, mock_view)

        presenter.success_callback()

        mock_view.set_error_text.assert_called_with(None)
        self.assertFalse(presenter.error_state)
    def test_configure_curves_tab_fails_silently_when_curves_tab_not_exists(
            self):
        fig = figure()
        ax = fig.add_subplot(111)
        mock_view = Mock()
        presenter = PlotConfigDialogPresenter(fig, mock_view)
        self.assertIsNone(presenter.tab_widget_presenters[2])

        presenter.configure_curves_tab(ax, None)

        mock_view.set_current_tab_widget.assert_not_called()
Exemple #5
0
def _run_apply_properties_on_figure_with_legend():
    fig = figure()
    ax = fig.add_subplot(111)
    ax.plot([1, 2, 3], label='old label')
    legend = ax.legend()
    legend.get_frame().set_alpha(0.5)
    presenter = PlotConfigDialogPresenter(fig, view=Mock())
    with patch.object(presenter.tab_widget_presenters[1], 'update_view',
                      lambda: None):
        presenter.apply_properties()
    return ax
    def test_error_callback(self):
        exception_string = "test string"

        fig = figure()
        fig.canvas.draw = Mock()
        mock_view = Mock()
        presenter = PlotConfigDialogPresenter(fig, mock_view)

        presenter.error_callback(exception_string)

        mock_view.set_error_text.assert_called_with(exception_string)
        self.assertTrue(presenter.error_state)
    def test_configure_curves_tab_succeeds_when_curve_and_axes_exist(self):
        fig = figure()
        ax = fig.add_subplot(111)
        curve = ax.plot([0], [0])
        mock_view = Mock()
        presenter = PlotConfigDialogPresenter(fig, mock_view)
        mock_curves_presenter = presenter.tab_widget_presenters[2]
        mock_curves_view, _ = presenter.tab_widget_views[1]

        presenter.configure_curves_tab(ax, curve)

        mock_curves_presenter.set_axes_from_object.assert_called()
        mock_view.set_current_tab_widget.assert_called_with(mock_curves_view)
        mock_view.set_current_tab_widget.assert_called()
    def test_configure_curves_tab_fails_silently_when_no_curves_on_axes(self):
        fig, (ax0, ax1) = subplots(2, subplot_kw={'projection': 'mantid'})
        ax0.plot([0],
                 [0])  # One axes must have a curve for curves tab to exist
        mock_view = Mock()
        presenter = PlotConfigDialogPresenter(fig, mock_view)
        mock_curves_presenter = presenter.tab_widget_presenters[2]
        mock_curves_presenter.set_axes_from_object.side_effect = ValueError(
            "Axes object does not exist in curves tab")

        presenter.configure_curves_tab(ax1, None)

        mock_curves_presenter.set_axes_from_object.assert_called()
        mock_view.set_current_tab_widget.assert_not_called()
Exemple #9
0
def _run_apply_properties_on_figure_with_image():
    img_fig = figure()
    img_ax = img_fig.add_subplot(111)
    image = img_ax.imshow([[0, 1], [0, 1]])
    cb = img_fig.colorbar(image)
    cb.set_label('old label')

    with patch.object(AxesTabWidgetPresenter, 'update_view',
                      mock_axes_tab_presenter_update_view):
        presenter = PlotConfigDialogPresenter(img_fig, view=Mock())
    with patch.object(presenter.tab_widget_presenters[1], 'update_view',
                      lambda: None):
        with patch.object(presenter.tab_widget_presenters[1], 'axis_changed',
                          lambda: None):
            presenter.apply_properties()
    return img_ax
def _run_apply_properties_on_figure_with_curve():
    fig = figure()
    ax = fig.add_subplot(111)
    ax.errorbar([0, 1], [0, 1], yerr=[0.1, 0.2], label='old label')

    with patch.object(AxesTabWidgetPresenter, 'update_view',
                      mock_axes_tab_presenter_update_view):
        presenter = PlotConfigDialogPresenter(fig, view=Mock())
    presenter.tab_widget_views[1][
        0].select_curve_combo_box.currentIndex.return_value = 0
    with patch.object(presenter.tab_widget_presenters[1], 'update_view',
                      lambda: None):
        with patch.object(presenter.tab_widget_presenters[1], 'axis_changed',
                          lambda: None):
            presenter.apply_properties()
    return ax
def _run_apply_properties_on_figure_with_legend(curve_view_mock):
    fig = figure()
    ax = fig.add_subplot(111)
    ax.plot([1, 2, 3], label='old label')
    legend = ax.legend()
    legend.get_frame().set_alpha(0.5)
    curve_view_mock.get_current_curve_name = CurveNameSideEffect(
        'old label', 'New label', switch_count=3)

    with patch.object(AxesTabWidgetPresenter, 'update_view',
                      mock_axes_tab_presenter_update_view):
        presenter = PlotConfigDialogPresenter(fig, view=Mock())
    with patch.object(presenter.tab_widget_presenters[1], 'update_view',
                      lambda: None):
        with patch.object(presenter.tab_widget_presenters[1], 'axis_changed',
                          lambda: None):
            presenter.apply_properties()
    return ax
    def test_configure_curves_tab_fails_silently_when_curve_not_found_in_curves_tab(
            self):
        fig = figure()
        ax = fig.add_subplot(111)
        ax.plot(
            [0], [0]
        )  # Must plot curve for curves tab to exist, hence why we dont use this in the call
        mock_view = Mock()
        presenter = PlotConfigDialogPresenter(fig, mock_view)
        mock_curves_presenter = presenter.tab_widget_presenters[2]
        mock_curves_presenter.set_curve_from_object.side_effect = ValueError(
            "Curve object does not exist in curves tab")
        mock_curves_view, _ = presenter.tab_widget_views[1]

        presenter.configure_curves_tab(ax, Mock())

        mock_curves_presenter.set_axes_from_object.assert_called()
        mock_view.set_current_tab_widget.assert_called_with(mock_curves_view)
        mock_view.set_current_tab_widget.assert_called()
def _run_apply_properties_on_figure_with_curve(curve_view_mock):
    fig = figure()
    ax = fig.add_subplot(111)
    ax.errorbar([0, 1], [0, 1], yerr=[0.1, 0.2], label='old label')
    ax.containers[0][2][0].axes.creation_args = [{'errorevery': 2}]
    curve_view_mock.get_current_curve_name = CurveNameSideEffect(
        'old label', 'New label', switch_count=6)

    with patch.object(AxesTabWidgetPresenter, 'update_view',
                      mock_axes_tab_presenter_update_view):
        presenter = PlotConfigDialogPresenter(fig, view=Mock())
    presenter.tab_widget_views[1][
        0].select_curve_combo_box.currentIndex.return_value = 0
    with patch.object(presenter.tab_widget_presenters[1], 'update_view',
                      lambda: None):
        with patch.object(presenter.tab_widget_presenters[1], 'axis_changed',
                          lambda: None):
            presenter.apply_properties()
    return ax
Exemple #14
0
 def test_correct_tabs_present_axes_only(self):
     fig = figure()
     fig.add_subplot(111)
     mock_view = Mock()
     presenter = PlotConfigDialogPresenter(fig, mock_view)
     expected_presenter_list = [self.axes_mock.return_value, None, None]
     self.assertEqual(expected_presenter_list,
                      presenter.tab_widget_presenters)
     mock_view.add_tab_widget.assert_called_once_with(
         (self.axes_mock.return_value.view, 'Axes'))
    def test_forget_tab_from_presenter_sets_presenter_and_view_to_none(self):
        fig = figure()
        ax = fig.add_subplot(111)
        ax.plot([0], [0])
        ax.legend()
        mock_view = Mock()
        presenter = PlotConfigDialogPresenter(fig, mock_view)

        mock_curves_presenter = presenter.tab_widget_presenters[2]
        mock_curves_view = mock_curves_presenter.view

        self.assertTrue(
            mock_curves_presenter in presenter.tab_widget_presenters)
        self.assertTrue((mock_curves_view,
                         'Curves') in presenter.tab_widget_views)

        presenter.forget_tab_from_presenter(mock_curves_presenter)

        self.assertTrue(
            mock_curves_presenter not in presenter.tab_widget_presenters)
        self.assertTrue((mock_curves_view,
                         'Curves') not in presenter.tab_widget_views)
    def test_tabs_present_updated_properties_from_figure_when_apply_clicked(
            self):
        fig = figure()
        ax = fig.add_subplot(111)
        ax.plot([0], [0])
        mock_view = Mock()
        presenter = PlotConfigDialogPresenter(fig, mock_view)

        # use mock manager to ensure all user properties are applied before view update
        mock_axes_presenter = presenter.tab_widget_presenters[1]
        mock_curves_presenter = presenter.tab_widget_presenters[2]
        mock_manager = Mock()
        mock_manager.attach_mock(mock_axes_presenter, "mock_axes_presenter")
        mock_manager.attach_mock(mock_curves_presenter,
                                 "mock_curves_presenter")

        presenter.apply_properties()
        mock_manager.assert_has_calls([
            call.mock_curves_presenter.apply_properties,
            call.mock_axes_presenter.apply_properties,
            call.mock_curves_presenter.update_view,
            call.mock_axes_presenter.update_view
        ])
Exemple #17
0
 def test_correct_tabs_present_axes_and_image_colormesh(self):
     fig = figure()
     ax = fig.add_subplot(111)
     ax.pcolormesh([[0, 1], [1, 0]])
     mock_view = Mock()
     presenter = PlotConfigDialogPresenter(fig, mock_view)
     expected_presenter_list = [
         self.axes_mock.return_value, None, self.images_mock.return_value
     ]
     self.assertEqual(expected_presenter_list,
                      presenter.tab_widget_presenters)
     expected_call_args = [(self.axes_mock.return_value.view, 'Axes'),
                           (self.images_mock.return_value.view, 'Images')]
     self.assert_called_x_times_with(2, expected_call_args,
                                     mock_view.add_tab_widget)
Exemple #18
0
 def test_correct_tabs_present_axes_and_curve_with_errors(self):
     fig = figure()
     ax = fig.add_subplot(111)
     ax.errorbar([0], [0], yerr=[1])
     mock_view = Mock()
     presenter = PlotConfigDialogPresenter(fig, mock_view)
     expected_presenter_list = [
         self.axes_mock.return_value, self.curves_mock.return_value, None
     ]
     self.assertEqual(expected_presenter_list,
                      presenter.tab_widget_presenters)
     expected_call_args = [(self.axes_mock.return_value.view, 'Axes'),
                           (self.curves_mock.return_value.view, 'Curves')]
     self.assert_called_x_times_with(2, expected_call_args,
                                     mock_view.add_tab_widget)
    def test_apply_all_properties_and_exist_does_exit_if_error_state_false(
            self):
        fig = figure()
        fig.canvas.draw = Mock()
        mock_view = Mock()
        presenter = PlotConfigDialogPresenter(fig, mock_view)
        presenter.apply_properties = Mock()
        presenter.error_state = False

        presenter.apply_properties_and_exit()

        mock_view.close.assert_called()
 def test_correct_tabs_present_axes_curves_and_legend(self):
     fig = figure()
     ax = fig.add_subplot(111)
     ax.plot([0])
     ax.legend(['Label'])
     mock_view = Mock()
     presenter = PlotConfigDialogPresenter(fig, mock_view)
     expected_presenter_list = [
         self.legend_mock.return_value, self.axes_mock.return_value,
         self.curves_mock.return_value, None
     ]
     self.assertEqual(expected_presenter_list,
                      presenter.tab_widget_presenters)
     expected_call_args = [(self.axes_mock.return_value.view, 'Axes'),
                           (self.curves_mock.return_value.view, 'Curves'),
                           (self.legend_mock.return_value.view, 'Legend')]
     self.assert_called_x_times_with(3, expected_call_args,
                                     mock_view.add_tab_widget)
    def test_apply_properties_calls_success_callback_on_canvas_draw_success(
            self):
        fig = figure()
        fig.canvas.draw = Mock()
        mock_view = Mock()
        presenter = PlotConfigDialogPresenter(fig, mock_view)
        presenter.success_callback = Mock()
        presenter.error_callback = Mock()

        presenter.apply_properties()

        presenter.success_callback.assert_called()
        presenter.error_callback.assert_not_called()
 def test_correct_tabs_present_axes_curves_and_image(self):
     fig = figure()
     ax = fig.add_subplot(211)
     ax.imshow([[0, 1], [1, 0]])
     ax1 = fig.add_subplot(212)
     ax1.errorbar([0], [0], yerr=[1])
     mock_view = Mock()
     presenter = PlotConfigDialogPresenter(fig, mock_view)
     expected_presenter_list = [
         None, self.axes_mock.return_value, self.curves_mock.return_value,
         self.images_mock.return_value
     ]
     self.assertEqual(expected_presenter_list,
                      presenter.tab_widget_presenters)
     expected_call_args = [(self.axes_mock.return_value.view, 'Axes'),
                           (self.curves_mock.return_value.view, 'Curves'),
                           (self.images_mock.return_value.view, 'Images')]
     self.assert_called_x_times_with(3, expected_call_args,
                                     mock_view.add_tab_widget)
    def test_apply_properties_calls_error_callback_when_exception_raised_in_canvas_draw(
            self):
        canvas_draw_exception = Exception("Exception in canvas.draw")

        def raise_():
            raise canvas_draw_exception

        fig = figure()
        fig.canvas.draw = Mock(side_effect=lambda: raise_())
        mock_view = Mock()
        presenter = PlotConfigDialogPresenter(fig, mock_view)
        presenter.success_callback = Mock()
        presenter.error_callback = Mock()
        mock_presenters = [Mock(), Mock(), Mock(), Mock()]
        presenter.tab_widget_presenters = mock_presenters

        presenter.apply_properties()

        presenter.error_callback.assert_called_with(str(canvas_draw_exception))
        presenter.success_callback.assert_not_called()
        for mock in presenter.tab_widget_presenters:
            mock.update_view.assert_not_called()
Exemple #24
0
 def launch_plot_options_on_curves_tab(self, axes, curve):
     self.plot_options_dialog = PlotConfigDialogPresenter(
         self.canvas.figure, parent=self.window)
     self.plot_options_dialog.configure_curves_tab(axes, curve)
Exemple #25
0
 def launch_plot_options(self):
     self.plot_options_dialog = PlotConfigDialogPresenter(
         self.canvas.figure, parent=self.window)
Exemple #26
0
class FigureManagerWorkbench(FigureManagerBase, QObject):
    """
    Attributes
    ----------
    canvas : `FigureCanvas`
        The FigureCanvas instance
    num : int or str
        The Figure number
    toolbar : qt.QToolBar
        The qt.QToolBar
    window : qt.QMainWindow
        The qt.QMainWindow

    """
    def __init__(self, canvas, num):
        assert QAppThreadCall.is_qapp_thread(
        ), "FigureManagerWorkbench cannot be created outside of the QApplication thread"
        QObject.__init__(self)

        parent, flags = get_window_config()
        self.window = FigureWindow(canvas, parent=parent, window_flags=flags)
        self.window.activated.connect(self._window_activated)
        self.window.closing.connect(canvas.close_event)
        self.window.closing.connect(self.destroy)
        self.window.visibility_changed.connect(self.fig_visibility_changed)

        self.window.setWindowTitle("Figure %d" % num)
        canvas.figure.set_label("Figure %d" % num)

        FigureManagerBase.__init__(self, canvas, num)
        # Give the keyboard focus to the figure instead of the
        # manager; StrongFocus accepts both tab and click to focus and
        # will enable the canvas to process event w/o clicking.
        # ClickFocus only takes the focus is the window has been
        # clicked
        # on. http://qt-project.org/doc/qt-4.8/qt.html#FocusPolicy-enum or
        # http://doc.qt.digia.com/qt/qt.html#FocusPolicy-enum
        canvas.setFocusPolicy(Qt.StrongFocus)
        canvas.setFocus()

        self.window._destroying = False

        # add text label to status bar
        self.statusbar_label = QLabel()
        self.window.statusBar().addWidget(self.statusbar_label)

        self.plot_options_dialog = None
        self.toolbar = self._get_toolbar(canvas, self.window)
        if self.toolbar is not None:
            self.window.addToolBar(self.toolbar)
            self.toolbar.message.connect(self.statusbar_label.setText)
            self.toolbar.sig_grid_toggle_triggered.connect(self.grid_toggle)
            self.toolbar.sig_toggle_fit_triggered.connect(self.fit_toggle)
            self.toolbar.sig_toggle_superplot_triggered.connect(
                self.superplot_toggle)
            self.toolbar.sig_copy_to_clipboard_triggered.connect(
                self.copy_to_clipboard)
            self.toolbar.sig_plot_options_triggered.connect(
                self.launch_plot_options)
            self.toolbar.sig_plot_help_triggered.connect(self.launch_plot_help)
            self.toolbar.sig_generate_plot_script_clipboard_triggered.connect(
                self.generate_plot_script_clipboard)
            self.toolbar.sig_generate_plot_script_file_triggered.connect(
                self.generate_plot_script_file)
            self.toolbar.sig_home_clicked.connect(
                self.set_figure_zoom_to_display_all)
            self.toolbar.sig_waterfall_reverse_order_triggered.connect(
                self.waterfall_reverse_line_order)
            self.toolbar.sig_waterfall_offset_amount_triggered.connect(
                self.launch_waterfall_offset_options)
            self.toolbar.sig_waterfall_fill_area_triggered.connect(
                self.launch_waterfall_fill_area_options)
            self.toolbar.sig_waterfall_conversion.connect(
                self.update_toolbar_waterfall_plot)
            self.toolbar.sig_change_line_collection_colour_triggered.connect(
                self.change_line_collection_colour)
            self.toolbar.setFloatable(False)
            tbs_height = self.toolbar.sizeHint().height()
        else:
            tbs_height = 0

        # resize the main window so it will display the canvas with the
        # requested size:
        cs = canvas.sizeHint()
        sbs = self.window.statusBar().sizeHint()
        self._status_and_tool_height = tbs_height + sbs.height()
        height = cs.height() + self._status_and_tool_height
        self.window.resize(cs.width(), height)

        self.fit_browser = FitPropertyBrowser(
            canvas, ToolbarStateManager(self.toolbar))
        self.fit_browser.closing.connect(self.handle_fit_browser_close)
        self.window.setCentralWidget(canvas)
        self.window.addDockWidget(Qt.LeftDockWidgetArea, self.fit_browser)

        self.superplot = None

        # Need this line to stop the bug where the dock window snaps back to its original size after resizing.
        # 0 argument is arbitrary and has no effect on fit widget size
        # This is a qt bug reported at (https://bugreports.qt.io/browse/QTBUG-65592)
        if QT_VERSION >= LooseVersion("5.6"):
            self.window.resizeDocks([self.fit_browser], [1], Qt.Horizontal)
        self.fit_browser.hide()

        if matplotlib.is_interactive():
            self.window.show()
            canvas.draw_idle()

        def notify_axes_change(fig):
            # This will be called whenever the current axes is changed
            if self.toolbar is not None:
                self.toolbar.update()

        canvas.figure.add_axobserver(notify_axes_change)

        # Register canvas observers
        self._fig_interaction = FigureInteraction(self)
        self._ads_observer = FigureManagerADSObserver(self)

        self.window.raise_()

    def full_screen_toggle(self):
        if self.window.isFullScreen():
            self.window.showNormal()
        else:
            self.window.showFullScreen()

    def _window_activated(self):
        GlobalFigureManager.set_active(self)

    def _get_toolbar(self, canvas, parent):
        return WorkbenchNavigationToolbar(canvas, parent, False)

    def resize(self, width, height):
        """Set the canvas size in pixels"""
        self.window.resize(width, height + self._status_and_tool_height)

    def show(self):
        self.window.show()
        self.window.activateWindow()
        self.window.raise_()
        if self.window.windowState() & Qt.WindowMinimized:
            # windowState() stores a combination of window state enums
            # and multiple window states can be valid. On Windows
            # a window can be both minimized and maximized at the
            # same time, so we make a check here. For more info see:
            # http://doc.qt.io/qt-5/qt.html#WindowState-enum
            if self.window.windowState() & Qt.WindowMaximized:
                self.window.setWindowState(Qt.WindowMaximized)
            else:
                self.window.setWindowState(Qt.WindowNoState)

        # Hack to ensure the canvas is up to date
        self.canvas.draw_idle()

        if self.toolbar:
            self.toolbar.set_buttons_visibility(self.canvas.figure)

    def destroy(self, *args):
        # check for qApp first, as PySide deletes it in its atexit handler
        if QApplication.instance() is None:
            return

        if self.window._destroying:
            return
        self.window._destroying = True

        if self.toolbar:
            self.toolbar.destroy()

        self._ads_observer.observeAll(False)
        self._ads_observer = None
        # disconnect window events before calling GlobalFigureManager.destroy. window.close is not guaranteed to
        # delete the object and do this for us. On macOS it was observed that closing the figure window
        # would produce an extraneous activated event that would add a new figure to the plots list
        # right after deleted the old one.
        self.window.disconnect()
        self._fig_interaction.disconnect()
        self.window.close()
        if self.superplot:
            self.superplot.close()

        try:
            GlobalFigureManager.destroy(self.num)
        except AttributeError:
            pass
            # It seems that when the python session is killed,
            # GlobalFigureManager can get destroyed before the GlobalFigureManager.destroy
            # line is run, leading to a useless AttributeError.

    def launch_plot_options(self):
        self.plot_options_dialog = PlotConfigDialogPresenter(
            self.canvas.figure, parent=self.window)

    def launch_plot_options_on_curves_tab(self, axes, curve):
        self.plot_options_dialog = PlotConfigDialogPresenter(
            self.canvas.figure, parent=self.window)
        self.plot_options_dialog.configure_curves_tab(axes, curve)

    def launch_plot_help(self):
        PlotHelpPages.show_help_page_for_figure(self.canvas.figure)

    def copy_to_clipboard(self):
        """Copy the current figure image to clipboard"""
        # store the image in a buffer using savefig(), this has the
        # advantage of applying all the default savefig parameters
        # such as background color; those would be ignored if you simply
        # grab the canvas using Qt
        buf = io.BytesIO()
        self.canvas.figure.savefig(buf)
        QApplication.clipboard().setImage(QImage.fromData(buf.getvalue()))
        buf.close()

    def grid_toggle(self, on):
        """Toggle grid lines on/off"""
        canvas = self.canvas
        axes = canvas.figure.get_axes()
        for ax in axes:
            if type(ax) == Axes:
                # Colorbar
                continue
            elif isinstance(ax, Axes3D):
                # The grid toggle function for 3D plots doesn't let you choose between major and minor lines.
                ax.grid(on)
            else:
                which = 'both' if hasattr(
                    ax, 'show_minor_gridlines'
                ) and ax.show_minor_gridlines else 'major'
                ax.grid(on, which=which)
        canvas.draw_idle()

    def fit_toggle(self):
        """Toggle fit browser and tool on/off"""
        if self.fit_browser.isVisible():
            self.fit_browser.hide()
            self.toolbar._actions["toggle_fit"].setChecked(False)
        else:
            if self.toolbar._actions["toggle_superplot"].isChecked():
                self._superplot_hide()
            self.fit_browser.show()

    def _superplot_show(self):
        """Show the superplot"""
        self.superplot = Superplot(self.canvas, self.window)
        if not self.superplot.is_valid():
            logger.warning("Superplot cannot be opened on data not linked "
                           "to a workspace.")
            self.superplot = None
            self.toolbar._actions["toggle_superplot"].setChecked(False)
        else:
            self.superplot.show()
            self.toolbar._actions["toggle_superplot"].setChecked(True)

    def _superplot_hide(self):
        """Hide the superplot"""
        if self.superplot is None:
            return
        self.superplot.close()
        self.superplot = None
        self.toolbar._actions["toggle_superplot"].setChecked(False)

    def superplot_toggle(self):
        """Toggle superplot dockwidgets on/off"""
        if self.superplot:
            self._superplot_hide()
        else:
            if self.toolbar._actions["toggle_fit"].isChecked():
                self.fit_toggle()
            self._superplot_show()

    def handle_fit_browser_close(self):
        """
        Respond to a signal that user closed self.fit_browser by
        clicking the [x] button.
        """
        self.toolbar.trigger_fit_toggle_action()

    def hold(self):
        """ Mark this figure as held"""
        self.toolbar.hold()

    def get_window_title(self):
        return self.window.windowTitle()

    def set_window_title(self, title):
        self.window.setWindowTitle(title)
        # We need to add a call to the figure manager here to call
        # notify methods when a figure is renamed, to update our
        # plot list.
        GlobalFigureManager.figure_title_changed(self.num)

        # For the workbench we also keep the label in sync, this is
        # to allow getting a handle as plt.figure('Figure Name')
        self.canvas.figure.set_label(title)

    def fig_visibility_changed(self):
        """
        Make a notification in the global figure manager that
        plot visibility was changed. This method is added to this
        class so that it can be wrapped in a QAppThreadCall.
        """
        GlobalFigureManager.figure_visibility_changed(self.num)

    def generate_plot_script_clipboard(self):
        script = generate_script(self.canvas.figure, exclude_headers=True)
        QApplication.clipboard().setText(script)
        logger.notice("Plotting script copied to clipboard.")

    def generate_plot_script_file(self):
        script = generate_script(self.canvas.figure)
        filepath = open_a_file_dialog(parent=self.canvas,
                                      default_suffix=".py",
                                      file_filter="Python Files (*.py)",
                                      accept_mode=QFileDialog.AcceptSave,
                                      file_mode=QFileDialog.AnyFile)
        if filepath:
            try:
                with open(filepath, 'w') as f:
                    f.write(script)
            except IOError as io_error:
                logger.error("Could not write file: {}\n{}"
                             "".format(filepath, io_error))

    def set_figure_zoom_to_display_all(self):
        axes = self.canvas.figure.get_axes()
        if axes:
            for ax in axes:
                # We check for axes type below as a pseudo check for an axes being
                # a colorbar. this is based on the same check in
                # FigureManagerADSObserver.deleteHandle.
                if type(ax) is not Axes:
                    if ax.lines:  # Relim causes issues with colour plots, which have no lines.
                        ax.relim()
                    elif isinstance(ax, Axes3D):
                        if hasattr(ax, 'original_data_surface'):
                            ax.collections[0]._vec = copy.deepcopy(
                                ax.original_data_surface)
                        elif hasattr(ax, 'original_data_wireframe'):
                            ax.collections[0].set_segments(
                                copy.deepcopy(ax.original_data_wireframe))
                        else:
                            ax.view_init()
                    elif ax.images:
                        axesfunctions.update_colorplot_datalimits(
                            ax, ax.images)
                        continue

                    ax.autoscale()

            self.canvas.draw()

    def waterfall_reverse_line_order(self):
        ax = self.canvas.figure.get_axes()[0]
        x, y = ax.waterfall_x_offset, ax.waterfall_y_offset
        fills = datafunctions.get_waterfall_fills(ax)
        ax.update_waterfall(0, 0)

        errorbar_cap_lines = datafunctions.remove_and_return_errorbar_cap_lines(
            ax)

        ax.lines.reverse()
        for cap in errorbar_cap_lines:
            ax.add_line(cap)
        if LooseVersion("3.7") > LooseVersion(
                matplotlib.__version__) >= LooseVersion("3.2"):
            for line_fill in fills:
                if line_fill not in ax.collections:
                    ax.add_collection(line_fill)
        elif LooseVersion(matplotlib.__version__) < LooseVersion("3.2"):
            ax.collections += fills
        else:
            raise NotImplementedError(
                "ArtistList will become an immutable tuple in matplotlib 3.7 and thus, "
                "this code doesn't work anymore.")
        ax.collections.reverse()
        ax.update_waterfall(x, y)

        if ax.get_legend():
            ax.make_legend()

        self.canvas.draw()

    def launch_waterfall_offset_options(self):
        WaterfallPlotOffsetDialogPresenter(self.canvas.figure,
                                           parent=self.window)

    def launch_waterfall_fill_area_options(self):
        WaterfallPlotFillAreaDialogPresenter(self.canvas.figure,
                                             parent=self.window)

    def update_toolbar_waterfall_plot(self, is_waterfall):
        self.toolbar.set_waterfall_options_enabled(is_waterfall)
        self.toolbar.set_fit_enabled(not is_waterfall)
        self.toolbar.set_generate_plot_script_enabled(not is_waterfall)

    def change_line_collection_colour(self, colour):
        for col in self.canvas.figure.get_axes()[0].collections:
            if isinstance(col, LineCollection):
                col.set_color(colour.name())

        self.canvas.draw()