Esempio n. 1
0
    def setUpClass(cls):
        cls.props_dict = {
            'label': 'ax0',
            'linestyle': '-.',
            'linewidth': 4,
            'drawstyle': 'steps',
            'color': '#ff0000',
            'marker': 'v',
            'markersize': 10,
            'markeredgecolor': 'g',
            'markeredgewidth': 0.4,
            'markerfacecolor': 'k',
            'visible': False
        }

        fig0 = figure()
        ax0 = fig0.add_subplot(211)
        ax0.plot([0, 1, 2], [0, 1, 2], **cls.props_dict)
        ax1 = fig0.add_subplot(212)
        ax1.errorbar([0, 2, 4], [0, 2, 4],
                     xerr=[0, 0.1, 0.2],
                     yerr=[0, 0.1, 0.2],
                     fmt='none',
                     label='ax1')
        cls.props = CurveProperties.from_curve(ax0.get_lines()[0])
        cls.error_props = CurveProperties.from_curve(ax1.containers[0])
Esempio n. 2
0
    def update_view(self, update_axes=True, update_curves=True):
        """Update the view with the selected axes and curve properties.
        By default we update everything since, if we changed something about
        the axes (e.g. title), we need to ensure these propagate to the curves tab.

        update_axes=True -> the axes combo will be updated
        update_curves=True -> the curves combo will be updated

        Regardless of the two parameters, the rest of the curves tab will update to show
        the properties of the selected curve."""

        if update_axes:
            # Update the 'select axes' combo box. Do this if axes properties have changed.
            self.axes_names_dict = get_axes_names_dict(self.fig,
                                                       curves_only=True)
            self.populate_select_axes_combo_box()
        if update_curves:
            # Update the 'select curves' combo box. Do this if curve properties have changed, or
            # if user selects a different set of axes.
            self._populate_select_curve_list()

        self.set_apply_to_all_buttons_enabled()

        # Then update the rest of the view to reflect the selected combo items.
        curve_props = CurveProperties.from_curve(self.get_current_curve())
        self.view.update_fields(curve_props)
        # only enable error bar tabs if we do not have multiple curves selected
        if not len(self.view.select_curve_list.selectedItems()) > 1:
            self.set_errorbars_tab_enabled()

        self.current_view_properties = curve_props
    def setUpClass(cls):
        # Mock axes tab view
        mock_axes_view = Mock(
            get_selected_ax_name=lambda: '(0, 0)',
            get_properties=lambda: AxProperties(new_ax_view_props))
        cls.ax_view_patch = patch(AX_VIEW, lambda x: mock_axes_view)
        cls.ax_view_mock = cls.ax_view_patch.start()

        # Mock curves tab view
        cls.curve_view_mock = Mock(
            get_selected_curve_name=lambda: 'old label',
            get_selected_ax_name=lambda: '(0, 0)',
            get_properties=lambda: CurveProperties(new_curve_view_props))
        cls.curve_view_patch = patch(CURVE_VIEW, lambda x: cls.curve_view_mock)
        cls.curve_view_patch.start()

        cls.ax = _run_apply_properties_on_figure_with_curve()
        cls.new_curve = cls.ax.containers[0]

        # Mock images tab view
        cls.img_view_mock = Mock(
            get_selected_image_name=lambda: '(0, 0) - old label',
            get_properties=lambda: ImageProperties(new_image_props))
        cls.img_view_patch = patch(IMAGE_VIEW, lambda x: cls.img_view_mock)
        cls.img_view_patch.start()

        cls.img_ax = _run_apply_properties_on_figure_with_image()
        cls.new_img = cls.img_ax.images[0]
Esempio n. 4
0
def _get_errorbar_specific_plot_kwargs(err_container):
    props = CurveProperties._get_errorbars_props_from_curve(err_container, {})
    props.pop('hide_errors')
    try:
        props['barsabove'] = err_container[2][0].zorder >= err_container[0].zorder
    except TypeError:  # Error when indexing err_container[0] when it has no line
        pass
    return props
Esempio n. 5
0
    def add_error_bars_menu(self, menu, ax):
        """
        Add menu actions to toggle the errors for all lines in the plot.

        Lines without errors are added in the context menu first,
        then lines containing errors are appended afterwards.

        This is done so that the context menu always has
        the same order of curves as the legend is currently showing - and the
        legend always appends curves with errors after the lines without errors.
        Relevant source, as of 10 July 2019:
        https://github.com/matplotlib/matplotlib/blob/154922992722db37a9d9c8680682ccc4acf37f8c/lib/matplotlib/legend.py#L1201

        :param menu: The menu to which the actions will be added
        :type menu: QMenu
        :param ax: The Axes containing lines to toggle errors on
        """
        # if the ax is not a MantidAxes, and there are no errors plotted,
        # then do not add any options for the menu
        if not isinstance(ax, MantidAxes) and len(ax.containers) == 0:
            return

        error_bars_menu = QMenu(self.ERROR_BARS_MENU_TEXT, menu)
        error_bars_menu.addAction(self.SHOW_ERROR_BARS_BUTTON_TEXT,
                                  partial(self.errors_manager.update_plot_after,
                                          self.errors_manager.toggle_all_errors, ax, make_visible=True))
        error_bars_menu.addAction(self.HIDE_ERROR_BARS_BUTTON_TEXT,
                                  partial(self.errors_manager.update_plot_after,
                                          self.errors_manager.toggle_all_errors, ax, make_visible=False))
        menu.addMenu(error_bars_menu)

        self.errors_manager.active_lines = self.errors_manager.get_curves_from_ax(ax)

        # if there's more than one line plotted, then
        # add a sub menu, containing an action to hide the
        # error bar for each line
        error_bars_menu.addSeparator()
        add_later = []
        for index, line in enumerate(self.errors_manager.active_lines):
            if curve_has_errors(line):
                curve_props = CurveProperties.from_curve(line)
                # Add lines without errors first, lines with errors are appended later. Read docstring for more info
                if not isinstance(line, ErrorbarContainer):
                    action = error_bars_menu.addAction(line.get_label(), partial(
                        self.errors_manager.update_plot_after, self.errors_manager.toggle_error_bars_for, ax, line))
                    action.setCheckable(True)
                    action.setChecked(not curve_props.hide_errors)
                else:
                    add_later.append((line.get_label(), partial(
                        self.errors_manager.update_plot_after, self.errors_manager.toggle_error_bars_for, ax, line),
                                      not curve_props.hide_errors))

        for label, function, visible in add_later:
            action = error_bars_menu.addAction(label, function)
            action.setCheckable(True)
            action.setChecked(visible)
 def test_errorevery_applied_correctly(self):
     fig = self.make_figure_with_error_bars()
     new_props = CurveProperties({'capsize': 1, 'errorevery': 7,
                                  'hide': False, 'marker': None,
                                  'label': "Workspace",
                                  'hide_errors': False})
     mock_view = Mock(get_selected_ax_name=lambda: "Axes 0: (0, 0)",
                      get_current_curve_name=lambda: "Workspace",
                      get_properties=lambda: new_props)
     presenter = self._generate_presenter(fig=fig, mock_view=mock_view)
     presenter.apply_properties()
     presenter.update_view()
     with patch.object(presenter.view, 'udpate_fields'):
         args, kwargs = presenter.view.update_fields.call_args
         self.assertEqual(args[0].errorevery, 7)
Esempio n. 7
0
    def toggle_error_bars_for(ax, curve, make_visible=None):
        # get all curve properties
        curve_props = CurveProperties.from_curve(curve)
        # and remove the ones that matplotlib doesn't recognise
        plot_kwargs = curve_props.get_plot_kwargs()
        new_curve = CurvesTabWidgetPresenter.replot_curve(
            ax, curve, plot_kwargs)

        # Inverts either the current state of hide_errors
        # or the make_visible kwarg that forces a state:
        # If make visible is True, then hide_errors must be False
        # for the intended effect
        curve_props.hide_errors = not curve_props.hide_errors if make_visible is None else not make_visible

        CurvesTabWidgetPresenter.toggle_errors(new_curve, curve_props)
        CurvesTabWidgetPresenter.update_limits_and_legend(ax)
Esempio n. 8
0
    def setUpClass(cls):
        # Mock axes tab view
        mock_axes_view = Mock(
            get_selected_ax_name=lambda: '(0, 0)',
            get_properties=lambda: AxProperties(new_ax_view_props))
        cls.ax_view_patch = patch(AX_VIEW, lambda x: mock_axes_view)
        cls.ax_view_mock = cls.ax_view_patch.start()

        # Mock curves tab view
        cls.curve_view_mock = Mock(
            get_selected_ax_name=lambda: '(0, 0)',
            select_curve_list=Mock(selectedItems=lambda: []),
            get_properties=lambda: CurveProperties(new_curve_view_props))
        cls.curve_view_patch = patch(CURVE_VIEW, lambda x: cls.curve_view_mock)
        cls.curve_view_patch.start()

        cls.ax = _run_apply_properties_on_figure_with_curve(
            cls.curve_view_mock)
        cls.new_curve = cls.ax.containers[0]

        # Mock images tab view
        if LooseVersion(matplotlib.__version__) > LooseVersion("3.1.3"):
            cls.img_view_mock = Mock(
                get_selected_image_name=lambda: '(0, 0) - child0',
                get_properties=lambda: ImageProperties(new_image_props))
        else:
            cls.img_view_mock = Mock(
                get_selected_image_name=lambda: '(0, 0) - image0',
                get_properties=lambda: ImageProperties(new_image_props))
        cls.img_view_patch = patch(IMAGE_VIEW, lambda x: cls.img_view_mock)
        cls.img_view_patch.start()

        cls.img_ax = _run_apply_properties_on_figure_with_image()
        cls.new_img = cls.img_ax.images[0]

        # Mock legend tab view
        cls.legend_view_mock = Mock(
            get_properties=lambda: LegendProperties(new_legend_props))
        cls.legend_view_patch = patch(LEGEND_VIEW,
                                      lambda x: cls.legend_view_mock)
        cls.legend_view_patch.start()

        cls.legend_ax = _run_apply_properties_on_figure_with_legend(
            cls.curve_view_mock)
        cls.new_legend = cls.legend_ax.get_legend()
Esempio n. 9
0
    def toggle_error_bars_for(cls, ax, curve, make_visible=None):
        # get legend properties
        if ax.legend_:
            legend_props = LegendProperties.from_legend(ax.legend_)
        else:
            legend_props = None

        if isinstance(curve, Line2D):
            curve_index = ax.get_lines().index(curve)
        else:
            curve_index = ax.get_lines().index(curve[0])

        # get all curve properties
        curve_props = CurveProperties.from_curve(curve)
        # and remove the ones that matplotlib doesn't recognise
        plot_kwargs = curve_props.get_plot_kwargs()
        new_curve = cls.replot_curve(ax, curve, plot_kwargs)

        if isinstance(ax, MantidAxes):
            errorbar_cap_lines = datafunctions.remove_and_return_errorbar_cap_lines(
                ax)
        else:
            errorbar_cap_lines = []

        ax.lines.insert(curve_index, ax.lines.pop())

        if isinstance(ax, MantidAxes) and ax.is_waterfall():
            datafunctions.convert_single_line_to_waterfall(ax, curve_index)

        for cap in errorbar_cap_lines:
            ax.add_line(cap)

        # Inverts either the current state of hide_errors
        # or the make_visible kwarg that forces a state:
        # If make visible is True, then hide_errors must be False
        # for the intended effect
        curve_props.hide_errors = not curve_props.hide_errors if make_visible is None else not make_visible

        cls.toggle_errors(new_curve, curve_props)
        cls.update_limits_and_legend(ax, legend_props)
 def test_update_view_called_on_init(self):
     presenter = self._generate_presenter()
     presenter.view.update_fields.assert_called_once_with(
         CurveProperties.from_curve(self.curve0))
Esempio n. 11
0
 def update_view(self):
     """Update the view with the selected curve's properties"""
     curve_props = CurveProperties.from_curve(self.get_selected_curve())
     self.view.update_fields(curve_props)
     self.set_errorbars_tab_enabled()
     self.current_view_properties = curve_props
Esempio n. 12
0
 def get_selected_curve_properties(self):
     """Get a CurveProperties object from the selected curve"""
     return CurveProperties.from_curve(self.get_selected_curve())
Esempio n. 13
0
 def get_properties(self):
     return CurveProperties.from_view(self)