Пример #1
0
    def _toggle_normalization(self, selected_ax):
        if figure_type(self.canvas.figure) == FigureType.Image and len(self.canvas.figure.get_axes()) > 1:
            axes = datafunctions.get_axes_from_figure(self.canvas.figure)
        else:
            axes = [selected_ax]

        for ax in axes:
            waterfall = isinstance(ax, MantidAxes) and ax.is_waterfall()
            if waterfall:
                x, y = ax.waterfall_x_offset, ax.waterfall_y_offset
                has_fill = ax.waterfall_has_fill()

                if has_fill:
                    line_colour_fill = datafunctions.waterfall_fill_is_line_colour(ax)
                    if line_colour_fill:
                        fill_colour = None
                    else:
                        fill_colour = datafunctions.get_waterfall_fills(ax)[0].get_facecolor()

                ax.update_waterfall(0, 0)

            # The colorbar can get screwed up with ragged workspaces and log scales as they go
            # through the normalisation toggle.
            # Set it to Linear and change it back after if necessary, since there's no reason
            # to duplicate the handling.
            colorbar_log = False
            if ax.images:
                colorbar_log = isinstance(ax.images[-1].norm, LogNorm)
                if colorbar_log:
                    self._change_colorbar_axes(Normalize)

            self._change_plot_normalization(ax)

            if ax.lines:  # Relim causes issues with colour plots, which have no lines.
                ax.relim()
                ax.autoscale()

            if ax.images:  # Colour bar limits are wrong if workspace is ragged. Set them manually.
                colorbar_min = np.nanmin(ax.images[-1].get_array())
                colorbar_max = np.nanmax(ax.images[-1].get_array())
                for image in ax.images:
                    image.set_clim(colorbar_min, colorbar_max)

                    # Update the colorbar label
                    cb = image.colorbar
                    if cb:
                        datafunctions.add_colorbar_label(cb, ax.get_figure().axes)
                if colorbar_log:  # If it had a log scaled colorbar before, put it back.
                    self._change_colorbar_axes(LogNorm)

                axesfunctions.update_colorplot_datalimits(ax, ax.images)

            datafunctions.set_initial_dimensions(ax)
            if waterfall:
                ax.update_waterfall(x, y)

                if has_fill:
                    ax.set_waterfall_fill(True, fill_colour)

        self.canvas.draw()
Пример #2
0
    def test_enabling_fill_with_line_colour_creates_fills_that_match_line_colour(
            self):
        self.presenter.view.enable_fill_group_box.isChecked.return_value = True
        self.presenter.view.use_line_colour_radio_button.isChecked.return_value = True
        self.presenter.set_fill_enabled()

        self.assertTrue(datafunctions.waterfall_fill_is_line_colour(self.ax))
Пример #3
0
    def _toggle_normalization(self, ax):
        waterfall = isinstance(ax, MantidAxes) and ax.is_waterfall()
        if waterfall:
            x, y = ax.waterfall_x_offset, ax.waterfall_y_offset
            has_fill = ax.waterfall_has_fill()

            if has_fill:
                line_colour_fill = datafunctions.waterfall_fill_is_line_colour(ax)
                if line_colour_fill:
                    fill_colour = None
                else:
                    fill_colour = datafunctions.get_waterfall_fills(ax)[0].get_facecolor()

            ax.update_waterfall(0, 0)

        is_normalized = self._is_normalized(ax)
        for arg_set in ax.creation_args:
            if arg_set['workspaces'] in ax.tracked_workspaces:
                workspace = ads.retrieve(arg_set['workspaces'])
                arg_set['distribution'] = is_normalized
                arg_set_copy = copy(arg_set)
                [
                    arg_set_copy.pop(key)
                    for key in ['function', 'workspaces', 'autoscale_on_update', 'norm']
                    if key in arg_set_copy.keys()
                ]
                if 'specNum' not in arg_set:
                    if 'wkspIndex' in arg_set:
                        arg_set['specNum'] = workspace.getSpectrum(
                            arg_set.pop('wkspIndex')).getSpectrumNo()
                    else:
                        raise RuntimeError("No spectrum number associated with plot of "
                                           "workspace '{}'".format(workspace.name()))
                # 2D plots have no spec number so remove it
                if figure_type(self.canvas.figure) == FigureType.Image:
                    arg_set_copy.pop('specNum')
                for ws_artist in ax.tracked_workspaces[workspace.name()]:
                    if ws_artist.spec_num == arg_set.get('specNum'):
                        ws_artist.is_normalized = not is_normalized
                        ws_artist.replace_data(workspace, arg_set_copy)
        if ax.lines:  # Relim causes issues with colour plots, which have no lines.
            ax.relim()

        if ax.images:  # Colour bar limits are wrong if workspace is ragged. Set them manually.
            colorbar_min = np.nanmin(ax.images[-1].get_array())
            colorbar_max = np.nanmax(ax.images[-1].get_array())
            for image in ax.images:
                image.set_clim(colorbar_min, colorbar_max)

        ax.autoscale()

        datafunctions.set_initial_dimensions(ax)
        if waterfall:
            ax.update_waterfall(x, y)

            if has_fill:
                ax.set_waterfall_fill(True, fill_colour)

        self.canvas.draw()
Пример #4
0
    def _replot_selected_curve(self, plot_kwargs):
        """Replot the selected curve with the given plot kwargs"""
        ax = self.get_selected_ax()
        curve = self.get_selected_curve()

        waterfall = False
        if isinstance(ax, MantidAxes):
            waterfall = ax.is_waterfall()
        check_line_colour = False
        # If the plot is a waterfall plot and the user has set it so the area under each line is filled, and the fill
        # colour for each line is set as the line colour, after the curve is updated we need to check if its colour has
        # changed so the fill can be updated accordingly.
        if waterfall and ax.waterfall_has_fill(
        ) and datafunctions.waterfall_fill_is_line_colour(ax):
            check_line_colour = True

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

        new_curve = FigureErrorsManager.replot_curve(ax, curve, plot_kwargs)
        self.curve_names_dict[self.view.get_selected_curve_name()] = new_curve

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

        # When a curve is redrawn it is moved to the back of the list of curves so here it is moved back to its previous
        # position. This is so that the correct offset is applied to the curve if the plot is a waterfall plot, but it
        # also just makes sense for the curve order to remain unchanged.
        ax.lines.insert(curve_index, ax.lines.pop())

        if waterfall:
            if check_line_colour:
                # curve can be either a Line2D or an ErrorContainer and the colour is accessed differently for each.
                if not errorbar:
                    # if the line colour hasn't changed then the fill colour doesn't need to be updated.
                    update_fill = curve.get_color() != new_curve[0].get_color()
                else:
                    update_fill = curve[0].get_color(
                    ) != new_curve[0].get_color()
                datafunctions.convert_single_line_to_waterfall(
                    ax, curve_index, need_to_update_fill=update_fill)
            else:
                # the curve has been reset to its original position so for a waterfall plot it needs to be re-offset.
                datafunctions.convert_single_line_to_waterfall(ax, curve_index)

            datafunctions.set_waterfall_fill_visible(ax, curve_index)

        ax.lines += errorbar_cap_lines
Пример #5
0
    def init_view(self):
        # This function sets the correct values in the menu when it is first opened.

        if self.ax.waterfall_has_fill():
            self.view.enable_fill_group_box.setChecked(True)

            if datafunctions.waterfall_fill_is_line_colour(self.ax):
                self.view.use_line_colour_radio_button.setChecked(True)
            else:
                self.view.use_solid_colour_radio_button.setChecked(True)
                poly = next(poly_collection for poly_collection in self.ax.collections
                            if isinstance(poly_collection, PolyCollection))
                self.view.colour_selector_widget.set_color(convert_color_to_hex(poly.get_facecolor().tolist()[0]))
Пример #6
0
    def _replot_current_curve(self, plot_kwargs):
        """Replot the selected curve with the given plot kwargs"""
        ax = self.get_selected_ax()
        curve = self.get_current_curve()

        waterfall = False
        if isinstance(ax, MantidAxes):
            waterfall = ax.is_waterfall()
        check_line_colour = False
        # If the plot is a waterfall plot and the user has set it so the area under each line is filled, and the fill
        # colour for each line is set as the line colour, after the curve is updated we need to check if its colour has
        # changed so the fill can be updated accordingly.
        if waterfall and ax.waterfall_has_fill() and datafunctions.waterfall_fill_is_line_colour(ax):
            check_line_colour = True

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

        # When you remove the curve on a waterfall plot, the remaining curves are repositioned so that they are
        # equally spaced apart. However since the curve is being replotted we don't want that to happen, so here
        # the waterfall offsets are set to 0 so the plot appears to be non-waterfall. The offsets are then re-set
        # after the curve is replotted.
        if waterfall:
            x_offset, y_offset = ax.waterfall_x_offset, ax.waterfall_y_offset
            ax.waterfall_x_offset = ax.waterfall_y_offset = 0

        new_curve = FigureErrorsManager.replot_curve(ax, curve, plot_kwargs)
        self.curve_names_dict[self.view.get_current_curve_name()] = new_curve

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

        # TODO: Accessing the ax.lines property is deprecated in mpl 3.5. It must be removed by mpl 3.7.
        with warnings.catch_warnings():
            warnings.simplefilter("ignore")
            # When a curve is redrawn it is moved to the back of the list of curves so here it is moved back to its previous
            # position. This is so that the correct offset is applied to the curve if the plot is a waterfall plot, but it
            # also just makes sense for the curve order to remain unchanged.
            ax.lines.insert(curve_index, ax.lines.pop())

        if waterfall:
            # Set the waterfall offsets to what they were previously.
            ax.waterfall_x_offset, ax.waterfall_y_offset = x_offset, y_offset
            if check_line_colour:
                # curve can be either a Line2D or an ErrorContainer and the colour is accessed differently for each.
                if not errorbar:
                    # if the line colour hasn't changed then the fill colour doesn't need to be updated.
                    update_fill = curve.get_color() != new_curve[0].get_color()
                else:
                    update_fill = curve[0].get_color() != new_curve[0].get_color()
                datafunctions.convert_single_line_to_waterfall(ax, curve_index, need_to_update_fill=update_fill)
            else:
                # the curve has been reset to its original position so for a waterfall plot it needs to be re-offset.
                datafunctions.convert_single_line_to_waterfall(ax, curve_index)

            datafunctions.set_waterfall_fill_visible(ax, curve_index)

        for cap in errorbar_cap_lines:
            ax.add_line(cap)