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
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
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)
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)
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)
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)
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
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