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()
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()
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 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() ax.autoscale() if waterfall: datafunctions.set_initial_dimensions(ax) ax.update_waterfall(x, y) self.canvas.draw()
def plot(workspaces, spectrum_nums=None, wksp_indices=None, errors=False, overplot=False, fig=None, plot_kwargs=None, ax_properties=None, window_title=None, tiled=False, waterfall=False, log_name=None, log_values=None): """ Create a figure with a single subplot and for each workspace/index add a line plot to the new axes. show() is called before returning the figure instance. A legend is added. :param workspaces: A list of workspace handles or strings :param spectrum_nums: A list of spectrum number identifiers (general start from 1) :param wksp_indices: A list of workspace indexes (starts from 0) :param errors: If true then error bars are added for each plot :param overplot: If true then overplot over the current figure if one exists. If an axis object the overplotting will be done on the axis passed in :param fig: If not None then use this Figure object to plot :param plot_kwargs: Arguments that will be passed onto the plot function :param ax_properties: A dict of axes properties. E.g. {'yscale': 'log'} :param window_title: A string denoting name of the GUI window which holds the graph :param tiled: An optional flag controlling whether to do a tiled or overlayed plot :param waterfall: An optional flag controlling whether or not to do a waterfall plot :param log_name: The optional log being plotted against. :param log_values: An optional list of log values to plot against. :return: The figure containing the plots """ plot_font = ConfigService.getString('plots.font') if plot_font: if len(mpl.rcParams['font.family']) > 1: mpl.rcParams['font.family'][0] = plot_font else: mpl.rcParams['font.family'].insert(0, plot_font) if plot_kwargs is None: plot_kwargs = {} _validate_plot_inputs(workspaces, spectrum_nums, wksp_indices, tiled, overplot) workspaces = [ws for ws in workspaces if isinstance(ws, MatrixWorkspace)] if spectrum_nums is not None: kw, nums = 'specNum', spectrum_nums else: kw, nums = 'wkspIndex', wksp_indices _add_default_plot_kwargs_from_settings(plot_kwargs, errors) num_axes = len(workspaces) * len(nums) if tiled else 1 fig, axes = get_plot_fig(overplot, ax_properties, window_title, num_axes, fig) # Convert to a MantidAxes if it isn't already. Ignore legend since # a new one will be drawn later axes = [ MantidAxes.from_mpl_axes(ax, ignore_artists=[Legend]) if not isinstance(ax, MantidAxes) else ax for ax in axes ] assert axes, "No axes are associated with this plot" if tiled: ws_index = [(ws, index) for ws in workspaces for index in nums] for index, ax in enumerate(axes): if index < len(ws_index): _do_single_plot(ax, [ws_index[index][0]], errors, False, [ws_index[index][1]], kw, plot_kwargs) else: ax.axis('off') else: show_title = ("on" == ConfigService.getString( "plots.ShowTitle").lower()) and not overplot ax = overplot if isinstance(overplot, MantidAxes) else axes[0] ax.axis('on') _do_single_plot(ax, workspaces, errors, show_title, nums, kw, plot_kwargs, log_name, log_values) # Can't have a waterfall plot with only one line. if len(nums) * len(workspaces) == 1 and waterfall: waterfall = False # The plot's initial xlim and ylim are used to offset each curve in a waterfall plot. # Need to do this whether the current curve is a waterfall plot or not because it may be converted later. if not overplot: datafunctions.set_initial_dimensions(ax) if waterfall: ax.set_waterfall(True) if not overplot: fig.canvas.set_window_title(figure_title(workspaces, fig.number)) else: if ax.is_waterfall(): for i in range(len(nums) * len(workspaces)): errorbar_cap_lines = datafunctions.remove_and_return_errorbar_cap_lines( ax) datafunctions.convert_single_line_to_waterfall( ax, len(ax.get_lines()) - (i + 1)) if ax.waterfall_has_fill(): datafunctions.waterfall_update_fill(ax) ax.lines += errorbar_cap_lines # update and show figure return _update_show_figure(fig)