示例#1
0
def _get_data_for_plot(axes, workspace, kwargs, with_dy=False, with_dx=False):
    if isinstance(workspace, mantid.dataobjects.MDHistoWorkspace):
        (normalization, kwargs) = get_normalization(workspace, **kwargs)
        indices, kwargs = get_indices(workspace, **kwargs)
        (x, y, dy) = get_md_data1d(workspace, normalization, indices)
        dx = None
        axis = None
    else:
        axis = MantidAxType(kwargs.pop("axis", MantidAxType.SPECTRUM))
        normalize_by_bin_width, kwargs = get_normalize_by_bin_width(
            workspace, axes, **kwargs)
        workspace_index, distribution, kwargs = get_wksp_index_dist_and_label(
            workspace, axis, **kwargs)
        if axis == MantidAxType.BIN:
            # Overwrite any user specified xlabel
            axes.set_xlabel("Spectrum")
            x, y, dy, dx = get_bins(workspace, workspace_index, with_dy)
        elif axis == MantidAxType.SPECTRUM:
            x, y, dy, dx = get_spectrum(workspace, workspace_index,
                                        normalize_by_bin_width, with_dy,
                                        with_dx)
        else:
            raise ValueError(
                "Axis {} is not a valid axis number.".format(axis))
        indices = None
    return x, y, dy, dx, indices, axis, kwargs
示例#2
0
def _plot_impl(axes, workspace, args, kwargs):
    """
    Compute data and labels for plot. Used by workspace
    replacement handlers to recompute data. See plot for
    argument details
    """
    if 'LogName' in kwargs:
        (x, y, FullTime, LogName, units,
         kwargs) = get_sample_log(workspace, **kwargs)
        axes.set_ylabel('{0} ({1})'.format(LogName, units))
        axes.set_xlabel('Time (s)')
        if FullTime:
            axes.xaxis_date()
            axes.xaxis.set_major_formatter(
                mdates.DateFormatter('%H:%M:%S\n%b-%d'))
            axes.set_xlabel('Time')
        kwargs['drawstyle'] = 'steps-post'
    else:
        normalize_by_bin_width, kwargs = get_normalize_by_bin_width(
            workspace, axes, **kwargs)
        x, y, _, _, indices, axis, kwargs = _get_data_for_plot(
            axes, workspace, kwargs)
        if kwargs.pop('update_axes_labels', True):
            _setLabels1D(axes,
                         workspace,
                         indices,
                         normalize_by_bin_width=normalize_by_bin_width,
                         axis=axis)
    kwargs.pop('normalize_by_bin_width', None)
    return x, y, args, kwargs
示例#3
0
def imshow(axes, workspace, *args, **kwargs):
    '''
    Essentially the same as :meth:`matplotlib.axes.Axes.imshow`.

    :param axes:      :class:`matplotlib.axes.Axes` object that will do the plotting
    :param workspace: :class:`mantid.api.MatrixWorkspace` or :class:`mantid.api.IMDHistoWorkspace`
                      to extract the data from
    :param distribution: ``None`` (default) asks the workspace. ``False`` means
                         divide by bin width. ``True`` means do not divide by bin width.
                         Applies only when the the matrix workspace is a histogram.
    :param normalization: ``None`` (default) ask the workspace. Applies to MDHisto workspaces. It can override
                          the value from displayNormalizationHisto. It checks only if
                          the normalization is mantid.api.MDNormalization.NumEventsNormalization
    :param indices: Specify which slice of an MDHistoWorkspace to use when plotting. Needs to be a tuple
                    and will be interpreted as a list of indices. You need to use ``slice(None)`` to
                    select which dimensions to plot. *e.g.* to select the last two axes to plot from a
                    3D volume use ``indices=(5, slice(None), slice(None))`` where the 5 is the bin selected
                    for the first axis.
    :param slicepoint: Specify which slice of an MDHistoWorkspace to use when plotting in the dimension units.
                       You need to use ``None`` to select which dimension to plot. *e.g.* to select the last
                       two axes to plot from a 3D volume use ``slicepoint=(1.0, None, None)`` where the 1.0 is
                       the value of the dimension selected for the first axis.
    :param axisaligned: ``False`` (default). If ``True``, or if the workspace has a variable
                        number of bins, the polygons will be aligned with the axes
    :param transpose: ``bool`` to transpose the x and y axes of the plotted dimensions of an MDHistoWorkspace
    '''
    transpose = kwargs.pop('transpose', False)
    if isinstance(workspace, mantid.dataobjects.MDHistoWorkspace):
        (normalization, kwargs) = get_normalization(workspace, **kwargs)
        indices, kwargs = get_indices(workspace, **kwargs)
        x, y, z = get_md_data2d_bin_bounds(workspace, normalization, indices,
                                           transpose)
        _setLabels2D(axes, workspace, indices, transpose)
    else:
        (aligned, kwargs) = check_resample_to_regular_grid(workspace, **kwargs)
        (normalize_by_bin_width,
         kwargs) = get_normalize_by_bin_width(workspace, axes, **kwargs)
        (distribution, kwargs) = get_distribution(workspace, **kwargs)
        if aligned:
            (x, y, z) = get_matrix_2d_ragged(workspace,
                                             normalize_by_bin_width,
                                             histogram2D=True,
                                             transpose=transpose)
        else:
            (x, y, z) = get_matrix_2d_data(workspace,
                                           distribution=distribution,
                                           histogram2D=True,
                                           transpose=transpose)
        _setLabels2D(axes,
                     workspace,
                     transpose=transpose,
                     normalize_by_bin_width=normalize_by_bin_width)
    if 'extent' not in kwargs:
        if x.ndim == 2 and y.ndim == 2:
            kwargs['extent'] = [x[0, 0], x[0, -1], y[0, 0], y[-1, 0]]
        else:
            kwargs['extent'] = [x[0], x[-1], y[0], y[-1]]
    return mantid.plots.modest_image.imshow(axes, z, *args, **kwargs)
示例#4
0
 def set_normalization(self, ws, **kwargs):
     normalize_by_bin_width, _ = get_normalize_by_bin_width(
         ws, self.ax, **kwargs)
     is_normalized = normalize_by_bin_width or ws.isDistribution()
     self.presenter.normalization = is_normalized
     if is_normalized:
         self.norm_opts.setCurrentIndex(1)
     else:
         self.norm_opts.setCurrentIndex(0)
示例#5
0
 def set_normalization(self, ws, **kwargs):
     normalize_by_bin_width, _ = get_normalize_by_bin_width(ws, self.ax, **kwargs)
     is_normalized = normalize_by_bin_width or ws.isDistribution()
     if is_normalized:
         self.presenter.normalization = mantid.api.MDNormalization.VolumeNormalization
         self.norm_opts.setCurrentIndex(1)
     else:
         self.presenter.normalization = mantid.api.MDNormalization.NoNormalization
         self.norm_opts.setCurrentIndex(0)
示例#6
0
def errorbar(axes, workspace, *args, **kwargs):
    """
    Unpack mantid workspace and render it with matplotlib. ``args`` and
    ``kwargs`` are passed to :py:meth:`matplotlib.axes.Axes.errorbar` after special
    keyword arguments are removed. This will automatically label the
    line according to the spectrum number unless specified otherwise.

    :param axes:      :class:`matplotlib.axes.Axes` object that will do the plotting
    :param workspace: :class:`mantid.api.MatrixWorkspace` or :class:`mantid.api.IMDHistoWorkspace`
                      to extract the data from
    :param specNum:   spectrum number to plot if MatrixWorkspace
    :param wkspIndex: workspace index to plot if MatrixWorkspace
    :param distribution: ``None`` (default) asks the global setting. ``False`` means
                         divide by bin width. ``True`` means do not divide by bin width.
                         Applies only when the the workspace is a MatrixWorkspace histogram.
    :param normalize_by_bin_width: Plot the workspace as a distribution. If None default to global
                                   setting: config['graph1d.autodistribution']
    :param normalization: ``None`` (default) ask the workspace. Applies to MDHisto workspaces. It can override
                          the value from displayNormalizationHisto. It checks only if
                          the normalization is mantid.api.MDNormalization.NumEventsNormalization
    :param axis: Specify which axis will be plotted. Use axis=MantidAxType.BIN to plot a bin,
                  and axis=MantidAxType.SPECTRUM to plot a spectrum.
                  The default value is axis=1, plotting spectra by default.
    :param indices: Specify which slice of an MDHistoWorkspace to use when plotting. Needs to be a tuple
                    and will be interpreted as a list of indices. You need to use ``slice(None)`` to
                    select which dimension to plot. *e.g.* to select the second axis to plot from a
                    3D volume use ``indices=(5, slice(None), 10)`` where the 5/10 are the bins selected
                    for the other 2 axes.
    :param slicepoint: Specify which slice of an MDHistoWorkspace to use when plotting in the dimension units.
                       You need to use ``None`` to select which dimension to plot. *e.g.* to select the second
                       axis to plot from a 3D volume use ``slicepoint=(1.0, None, 2.0)`` where the 1.0/2.0 are
                       the dimension selected for the other 2 axes.

    For matrix workspaces with more than one spectra, either ``specNum`` or ``wkspIndex``
    needs to be specified. Giving both will generate a :class:`RuntimeError`. There is no similar
    keyword for MDHistoWorkspaces. These type of workspaces have to have exactly one non integrated
    dimension
    """
    normalize_by_bin_width, kwargs = get_normalize_by_bin_width(
        workspace, axes, **kwargs)
    x, y, dy, dx, indices, axis, kwargs = _get_data_for_plot(axes,
                                                             workspace,
                                                             kwargs,
                                                             with_dy=True,
                                                             with_dx=False)
    if kwargs.pop('update_axes_labels', True):
        _setLabels1D(axes,
                     workspace,
                     indices,
                     normalize_by_bin_width=normalize_by_bin_width,
                     axis=axis)
    kwargs.pop('normalize_by_bin_width', None)

    return axes.errorbar(x, y, dy, dx, *args, **kwargs)
示例#7
0
def imshow_sampling(axes,
                    workspace,
                    cmap=None,
                    alpha=None,
                    vmin=None,
                    vmax=None,
                    shape=None,
                    filternorm=1,
                    filterrad=4.0,
                    imlim=None,
                    url=None,
                    **kwargs):
    """Copy of imshow but replaced AxesImage with SamplingImage and added
    callbacks and Mantid Workspace stuff.

    See :meth:`matplotlib.axes.Axes.imshow`

    To test:

    from mantidqt.widgets.sliceviewer.samplingimage import imshow_sampling
    fig, ax = plt.subplots()
    im = imshow_sampling(ax, workspace, aspect='auto', origin='lower')
    fig.show()
    """
    normalize_by_bin_width, kwargs = get_normalize_by_bin_width(workspace, axes, **kwargs)
    transpose = kwargs.pop('transpose', False)
    extent = kwargs.pop('extent', None)
    interpolation = kwargs.pop('interpolation', None)
    origin = kwargs.pop('origin', None)
    norm = kwargs.pop('norm', None)
    resample = kwargs.pop('resample', False)
    kwargs.pop('distribution', None)

    if not extent:
        x0, x1, y0, y1 = (workspace.getDimension(0).getMinimum(),
                          workspace.getDimension(0).getMaximum(),
                          workspace.getDimension(1).getMinimum(),
                          workspace.getDimension(1).getMaximum())
        if isinstance(workspace, MatrixWorkspace) and not workspace.isCommonBins():
            # for MatrixWorkspace the x extent obtained from dimension 0 corresponds to the first spectrum
            # this is not correct in case of ragged workspaces, where we need to obtain the global xmin and xmax
            # moreover the axis might be in ascending or descending order, so x[0] is not necessarily the minimum
            xmax, xmin = None, None  # don't initialise with values from first spectrum as could be a monitor
            si = workspace.spectrumInfo()
            for i in range(workspace.getNumberHistograms()):
                if si.hasDetectors(i) and not si.isMonitor(i):
                    x_axis = workspace.readX(i)
                    x_i_first = x_axis[0]
                    x_i_last = x_axis[-1]
                    x_i_min = min([x_i_first, x_i_last])
                    x_i_max = max([x_i_first, x_i_last])
                    # effectively ignore spectra with nan or inf values
                    if np.isfinite(x_i_min):
                        xmin = min([x_i_min, xmin]) if xmin else x_i_min
                    if np.isfinite(x_i_max):
                        xmax = max([x_i_max, xmax]) if xmax else x_i_max
            x0 = xmin if xmin else x0
            x1 = xmax if xmax else x1

        if workspace.getDimension(1).getNBins() == workspace.getAxis(1).length():
            width = workspace.getDimension(1).getBinWidth()
            y0 -= width / 2
            y1 += width / 2
        if origin == "upper":
            y0, y1 = y1, y0
        extent = (x0, x1, y0, y1)

        if transpose:
            e1, e2, e3, e4 = extent
            extent = e3, e4, e1, e2

    # from matplotlib.axes.Axes.imshow
    if norm is not None and not isinstance(norm, matplotlib.colors.Normalize):
        raise ValueError("'norm' must be an instance of 'mcolors.Normalize'")

    aspect = kwargs.pop('aspect', matplotlib.rcParams['image.aspect'])
    axes.set_aspect(aspect)

    im = SamplingImage(axes,
                       workspace,
                       transpose,
                       cmap,
                       norm,
                       interpolation,
                       origin,
                       extent,
                       filternorm=filternorm,
                       filterrad=filterrad,
                       resample=resample,
                       normalize_by_bin_width=normalize_by_bin_width,
                       **kwargs)
    im._resample_image(100, 100)

    im.set_alpha(alpha)
    im.set_url(url)
    if im.get_clip_path() is None:
        # image does not already have clipping set, clip to axes patch
        im.set_clip_path(axes.patch)
    if vmin is not None or vmax is not None:
        if norm is not None and isinstance(norm, matplotlib.colors.LogNorm):
            if vmin <= 0:
                vmin = 0.0001
            if vmax <= 0:
                vmax = 1
        im.set_clim(vmin, vmax)
    else:
        im.autoscale_None()

    # update ax.dataLim, and, if autoscaling, set viewLim
    # to tightly fit the image, regardless of dataLim.
    im.set_extent(im.get_extent())

    axes.add_image(im)
    if extent:
        axes.set_xlim(extent[0], extent[1])
        axes.set_ylim(extent[2], extent[3])

    im.connect_events()
    return im
示例#8
0
def imshow_sampling(axes,
                    workspace,
                    cmap=None,
                    alpha=None,
                    vmin=None,
                    vmax=None,
                    shape=None,
                    filternorm=1,
                    filterrad=4.0,
                    imlim=None,
                    url=None,
                    **kwargs):
    """Copy of imshow but replaced AxesImage with SamplingImage and added
    callbacks and Mantid Workspace stuff.

    See :meth:`matplotlib.axes.Axes.imshow`

    To test:

    from mantidqt.widgets.sliceviewer.samplingimage import imshow_sampling
    fig, ax = plt.subplots()
    im = imshow_sampling(ax, workspace, aspect='auto', origin='lower')
    fig.show()
    """
    normalize_by_bin_width, kwargs = get_normalize_by_bin_width(
        workspace, axes, **kwargs)
    transpose = kwargs.pop('transpose', False)
    extent = kwargs.pop('extent', None)
    interpolation = kwargs.pop('interpolation', None)
    origin = kwargs.pop('origin', None)
    norm = kwargs.pop('norm', None)
    resample = kwargs.pop('resample', False)
    kwargs.pop('distribution', None)

    if not extent:
        x0, x1, y0, y1 = (workspace.getDimension(0).getMinimum(),
                          workspace.getDimension(0).getMaximum(),
                          workspace.getDimension(1).getMinimum(),
                          workspace.getDimension(1).getMaximum())
        if workspace.getDimension(1).getNBins() == workspace.getAxis(
                1).length():
            width = workspace.getDimension(1).getBinWidth()
            y0 -= width / 2
            y1 += width / 2
        if origin == "upper":
            y0, y1 = y1, y0
        extent = (x0, x1, y0, y1)

        if transpose:
            e1, e2, e3, e4 = extent
            extent = e3, e4, e1, e2

    # from matplotlib.axes.Axes.imshow
    if norm is not None and not isinstance(norm, matplotlib.colors.Normalize):
        raise ValueError("'norm' must be an instance of 'mcolors.Normalize'")

    aspect = kwargs.pop('aspect', matplotlib.rcParams['image.aspect'])
    axes.set_aspect(aspect)

    im = SamplingImage(axes,
                       workspace,
                       transpose,
                       cmap,
                       norm,
                       interpolation,
                       origin,
                       extent,
                       filternorm=filternorm,
                       filterrad=filterrad,
                       resample=resample,
                       normalize_by_bin_width=normalize_by_bin_width,
                       **kwargs)
    im._resample_image(100, 100)

    im.set_alpha(alpha)
    im.set_url(url)
    if im.get_clip_path() is None:
        # image does not already have clipping set, clip to axes patch
        im.set_clip_path(axes.patch)
    if vmin is not None or vmax is not None:
        if norm is not None and isinstance(norm, matplotlib.colors.LogNorm):
            if vmin <= 0:
                vmin = 0.0001
            if vmax <= 0:
                vmax = 1
        im.set_clim(vmin, vmax)
    else:
        im.autoscale_None()

    # update ax.dataLim, and, if autoscaling, set viewLim
    # to tightly fit the image, regardless of dataLim.
    im.set_extent(im.get_extent())

    axes.add_image(im)
    if extent:
        axes.set_xlim(extent[0], extent[1])
        axes.set_ylim(extent[2], extent[3])

    im.connect_events()
    return im