示例#1
0
def errorbar(axes, workspace, *args, **kwargs):
    """
    Same as the cli PlotCut but returns the relevant axes object.
    """
    from mslice.app.presenters import get_cut_plotter_presenter
    cur_fig = plt.gcf()
    cur_canvas = cur_fig.canvas

    _check_workspace_name(workspace)
    workspace = get_workspace_handle(workspace)
    if not isinstance(workspace, HistogramWorkspace):
        raise RuntimeError("Incorrect workspace type.")

    presenter = get_cut_plotter_presenter()

    plot_over = kwargs.pop('plot_over', True)
    intensity_range = kwargs.pop('intensity_range', (None, None))
    label = kwargs.pop('label', None)
    label = workspace.name if label is None else label
    en_conversion_allowed = kwargs.pop('en_conversion', True)

    cut_axis, int_axis = tuple(workspace.axes)
    # Checks that current cut has consistent units with previous
    if plot_over:
        cached_cuts = presenter.get_cache(axes)
        if cached_cuts:
            if (cut_axis.units != cached_cuts[0].cut_axis.units):
                raise RuntimeError('Cut axes not consistent with current plot. '
                                   'Expected {}, got {}'.format(cached_cuts[0].cut_axis.units, cut_axis.units))
            # Checks whether we should do an energy unit conversion
            if 'DeltaE' in cut_axis.units and cut_axis.e_unit != cached_cuts[0].cut_axis.e_unit:
                if en_conversion_allowed:
                    _rescale_energy_cut_plot(presenter, cached_cuts, cut_axis.e_unit)
                else:
                    raise RuntimeError('Wrong energy unit for cut. '
                                       'Expected {}, got {}'.format(cached_cuts[0].cut_axis.e_unit, cut_axis.e_unit))

    plotfunctions.errorbar(axes, workspace.raw_ws, label=label, *args, **kwargs)

    axes.set_ylim(*intensity_range) if intensity_range is not None else axes.autoscale()
    intensity_min, intensity_max = axes.get_ylim()
    if cur_canvas.manager.window.action_toggle_legends.isChecked():
        leg = axes.legend(fontsize='medium')
        leg.draggable()
    axes.set_xlabel(get_display_name(cut_axis), picker=CUT_PICKER_TOL_PTS)
    axes.set_ylabel(CUT_INTENSITY_LABEL, picker=CUT_PICKER_TOL_PTS)
    if not plot_over:
        cur_canvas.set_window_title(workspace.name)
        cur_canvas.manager.update_grid()
    if not cur_canvas.manager.has_plot_handler():
        cur_canvas.manager.add_cut_plot(presenter, workspace.name)
    cur_fig.canvas.draw()
    axes.pchanged()  # This call is to let the waterfall callback know to update

    cut = Cut(cut_axis, int_axis, intensity_min, intensity_max, workspace.norm_to_one, width='')
    cut.workspace_name = workspace.parent
    presenter.save_cache(axes, cut, plot_over)

    return axes.lines
示例#2
0
 def _data_update(artists, workspace):
     # errorbar with workspaces can only return a single container
     container_orig = artists[0]
     # It is not possible to simply reset the error bars so
     # we have to plot new lines but ensure we don't reorder them on the plot!
     orig_idx = self.containers.index(container_orig)
     container_orig.remove()
     # The container does not remove itself from the containers list
     # but protect this just in case matplotlib starts doing this
     try:
         self.containers.remove(container_orig)
     except ValueError:
         pass
     # this gets pushed back onto the containers list
     container_new = plotfunctions.errorbar(self, workspace, **kwargs)
     self.containers.insert(orig_idx, container_new)
     self.containers.pop()
     # update line properties to match original
     orig_flat, new_flat = cbook.flatten(container_orig), cbook.flatten(container_new)
     for artist_orig, artist_new in zip(orig_flat, new_flat):
         artist_new.update_from(artist_orig)
     # ax.relim does not support collections...
     self._update_line_limits(container_new[0])
     self.autoscale()
     return container_new
示例#3
0
 def _data_update(artists, workspace):
     # errorbar with workspaces can only return a single container
     container_orig = artists[0]
     # It is not possible to simply reset the error bars so
     # we have to plot new lines but ensure we don't reorder them on the plot!
     orig_idx = self.containers.index(container_orig)
     container_orig.remove()
     # The container does not remove itself from the containers list
     # but protect this just in case matplotlib starts doing this
     try:
         self.containers.remove(container_orig)
     except ValueError:
         pass
     # this gets pushed back onto the containers list
     container_new = plotfunctions.errorbar(self, workspace,
                                            **kwargs)
     self.containers.insert(orig_idx, container_new)
     self.containers.pop()
     # update line properties to match original
     orig_flat, new_flat = cbook.flatten(
         container_orig), cbook.flatten(container_new)
     for artist_orig, artist_new in zip(orig_flat, new_flat):
         artist_new.update_from(artist_orig)
     # ax.relim does not support collections...
     self._update_line_limits(container_new[0])
     self.autoscale()
     return container_new
示例#4
0
    def errorbar(self, *args, **kwargs):
        """
        If the **mantid** projection is chosen, it can be
        used the same as :py:meth:`matplotlib.axes.Axes.errorbar` for arrays,
        or it can be used to plot :class:`mantid.api.MatrixWorkspace`
        or :class:`mantid.api.IMDHistoWorkspace`. You can have something like::

            import matplotlib.pyplot as plt
            from mantid import plots

            ...

            fig, ax = plt.subplots(subplot_kw={'projection':'mantid'})
            ax.errorbar(workspace,'rs',specNum=1) #for workspaces
            ax.errorbar(x,y,yerr,'bo')            #for arrays
            fig.show()

        For keywords related to workspaces, see :func:`plotfunctions.errorbar`
        """
        if helperfunctions.validate_args(*args):
            logger.debug('using plotfunctions')

            def _data_update(artists, workspace):
                # errorbar with workspaces can only return a single container
                container_orig = artists[0]
                # It is not possible to simply reset the error bars so
                # we have to plot new lines but ensure we don't reorder them on the plot!
                orig_idx = self.containers.index(container_orig)
                container_orig.remove()
                # The container does not remove itself from the containers list
                # but protect this just in case matplotlib starts doing this
                try:
                    self.containers.remove(container_orig)
                except ValueError:
                    pass
                # this gets pushed back onto the containers list
                container_new = plotfunctions.errorbar(self, workspace,
                                                       **kwargs)
                self.containers.insert(orig_idx, container_new)
                self.containers.pop()
                # update line properties to match original
                orig_flat, new_flat = cbook.flatten(
                    container_orig), cbook.flatten(container_new)
                for artist_orig, artist_new in zip(orig_flat, new_flat):
                    artist_new.update_from(artist_orig)
                # ax.relim does not support collections...
                self._update_line_limits(container_new[0])
                self.autoscale()
                return container_new

            workspace = args[0]
            spec_num = self._get_spec_number(workspace, kwargs)
            return self.track_workspace_artist(workspace,
                                               plotfunctions.errorbar(
                                                   self, *args, **kwargs),
                                               _data_update,
                                               spec_num=spec_num)
        else:
            return Axes.errorbar(self, *args, **kwargs)
示例#5
0
文件: __init__.py 项目: dpaj/mantid
            def _data_update(artists, workspace, new_kwargs=None):
                if self.lines:
                    self.set_autoscaley_on(autoscale_on_update)

                # errorbar with workspaces can only return a single container
                container_orig = artists[0]
                # It is not possible to simply reset the error bars so
                # we have to plot new lines but ensure we don't reorder them on the plot!
                orig_idx = self.containers.index(container_orig)
                container_orig.remove()
                # The container does not remove itself from the containers list
                # but protect this just in case matplotlib starts doing this
                try:
                    self.containers.remove(container_orig)
                except ValueError:
                    pass
                # this gets pushed back onto the containers list
                if new_kwargs:
                    container_new = plotfunctions.errorbar(self, workspace,
                                                           **new_kwargs)
                else:
                    container_new = plotfunctions.errorbar(self, workspace,
                                                           **kwargs)
                self.containers.insert(orig_idx, container_new)
                self.containers.pop()

                # Update joining line
                if container_new[0] and container_orig[0]:
                    container_new[0].update_from(container_orig[0])
                # Update caps
                for orig_caps, new_caps in zip(container_orig[1], container_new[1]):
                    new_caps.update_from(orig_caps)
                # Update bars
                for orig_bars, new_bars in zip(container_orig[2], container_new[2]):
                    new_bars.update_from(orig_bars)

                # Re-plotting in the config dialog will assign this attr
                if hasattr(container_orig, 'errorevery'):
                    setattr(container_new, 'errorevery', container_orig.errorevery)

                # ax.relim does not support collections...
                self._update_line_limits(container_new[0])
                self.set_autoscaley_on(True)
                return container_new
示例#6
0
    def errorbar(self, *args, **kwargs):
        """
        If the **mantid** projection is chosen, it can be
        used the same as :py:meth:`matplotlib.axes.Axes.errorbar` for arrays,
        or it can be used to plot :class:`mantid.api.MatrixWorkspace`
        or :class:`mantid.api.IMDHistoWorkspace`. You can have something like::

            import matplotlib.pyplot as plt
            from mantid import plots

            ...

            fig, ax = plt.subplots(subplot_kw={'projection':'mantid'})
            ax.errorbar(workspace,'rs',specNum=1) #for workspaces
            ax.errorbar(x,y,yerr,'bo')            #for arrays
            fig.show()

        For keywords related to workspaces, see :func:`plotfunctions.errorbar`
        """
        if helperfunctions.validate_args(*args):
            logger.debug('using plotfunctions')

            def _data_update(artists, workspace):
                # errorbar with workspaces can only return a single container
                container_orig = artists[0]
                # It is not possible to simply reset the error bars so
                # we have to plot new lines but ensure we don't reorder them on the plot!
                orig_idx = self.containers.index(container_orig)
                container_orig.remove()
                # The container does not remove itself from the containers list
                # but protect this just in case matplotlib starts doing this
                try:
                    self.containers.remove(container_orig)
                except ValueError:
                    pass
                # this gets pushed back onto the containers list
                container_new = plotfunctions.errorbar(self, workspace, **kwargs)
                self.containers.insert(orig_idx, container_new)
                self.containers.pop()
                # update line properties to match original
                orig_flat, new_flat = cbook.flatten(container_orig), cbook.flatten(container_new)
                for artist_orig, artist_new in zip(orig_flat, new_flat):
                    artist_new.update_from(artist_orig)
                # ax.relim does not support collections...
                self._update_line_limits(container_new[0])
                self.autoscale()
                return container_new

            workspace = args[0]
            spec_num = self._get_spec_number(workspace, kwargs)
            return self.track_workspace_artist(workspace,
                                               plotfunctions.errorbar(self, *args, **kwargs),
                                               _data_update, spec_num=spec_num)
        else:
            return Axes.errorbar(self, *args, **kwargs)
 def test_1d_errorbars(self):
     fig, ax = plt.subplots()
     funcs.errorbar(ax, self.ws2d_histo, 'rs', specNum=1)
     funcs.errorbar(ax, self.ws2d_histo, specNum=2, linewidth=6)
     funcs.errorbar(ax, self.ws_MD_1d, 'bo')
示例#8
0
 def test_1d_errorbars(self):
     fig, ax = plt.subplots()
     funcs.errorbar(ax, self.ws2d_histo, 'rs', specNum=1)
     funcs.errorbar(ax, self.ws2d_histo, specNum=2, linewidth=6)
     funcs.errorbar(ax, self.ws_MD_1d, 'bo')
示例#9
0
文件: __init__.py 项目: dpaj/mantid
    def errorbar(self, *args, **kwargs):
        """
        If the **mantid** projection is chosen, it can be
        used the same as :py:meth:`matplotlib.axes.Axes.errorbar` for arrays,
        or it can be used to plot :class:`mantid.api.MatrixWorkspace`
        or :class:`mantid.api.IMDHistoWorkspace`. You can have something like::

            import matplotlib.pyplot as plt
            from mantid import plots

            ...

            fig, ax = plt.subplots(subplot_kw={'projection':'mantid'})
            ax.errorbar(workspace,'rs',specNum=1) #for workspaces
            ax.errorbar(x,y,yerr,'bo')            #for arrays
            fig.show()

        For keywords related to workspaces, see :func:`plotfunctions.errorbar`
        """
        if helperfunctions.validate_args(*args):
            logger.debug('using plotfunctions')

            autoscale_on_update = kwargs.pop("autoscale_on_update", True)

            def _data_update(artists, workspace, new_kwargs=None):
                if self.lines:
                    self.set_autoscaley_on(autoscale_on_update)

                # errorbar with workspaces can only return a single container
                container_orig = artists[0]
                # It is not possible to simply reset the error bars so
                # we have to plot new lines but ensure we don't reorder them on the plot!
                orig_idx = self.containers.index(container_orig)
                container_orig.remove()
                # The container does not remove itself from the containers list
                # but protect this just in case matplotlib starts doing this
                try:
                    self.containers.remove(container_orig)
                except ValueError:
                    pass
                # this gets pushed back onto the containers list
                if new_kwargs:
                    container_new = plotfunctions.errorbar(self, workspace,
                                                           **new_kwargs)
                else:
                    container_new = plotfunctions.errorbar(self, workspace,
                                                           **kwargs)
                self.containers.insert(orig_idx, container_new)
                self.containers.pop()

                # Update joining line
                if container_new[0] and container_orig[0]:
                    container_new[0].update_from(container_orig[0])
                # Update caps
                for orig_caps, new_caps in zip(container_orig[1], container_new[1]):
                    new_caps.update_from(orig_caps)
                # Update bars
                for orig_bars, new_bars in zip(container_orig[2], container_new[2]):
                    new_bars.update_from(orig_bars)

                # Re-plotting in the config dialog will assign this attr
                if hasattr(container_orig, 'errorevery'):
                    setattr(container_new, 'errorevery', container_orig.errorevery)

                # ax.relim does not support collections...
                self._update_line_limits(container_new[0])
                self.set_autoscaley_on(True)
                return container_new

            workspace = args[0]
            spec_num = self.get_spec_number(workspace, kwargs)
            is_normalized, kwargs = get_normalize_by_bin_width(workspace, self,
                                                               **kwargs)

            if self.lines:
                self.set_autoscaley_on(autoscale_on_update)

            artist = self.track_workspace_artist(
                workspace, plotfunctions.errorbar(self, *args, **kwargs),
                _data_update, spec_num, is_normalized)

            self.set_autoscaley_on(True)
            return artist
        else:
            return Axes.errorbar(self, *args, **kwargs)