def test_cannot_make_waterfall_plot_with_one_line(self): fig = plt.figure() ws = self._test_ws plot([ws], wksp_indices=[1], fig=fig, waterfall=True) ax = plt.gca() self.assertFalse(ax.is_waterfall())
def test_workspace_tracked_when_plotting_over_scripted_fig(self): fig = plt.figure() plt.plot([0, 1], [0, 1]) ws = self._test_ws plot([ws], wksp_indices=[1], fig=fig, overplot=True) ax = plt.gca() self.assertIn(ws.name(), ax.tracked_workspaces)
def test_setting_waterfall_to_true_makes_waterfall_plot(self): fig = plt.figure() ws = self._test_ws plot([ws], wksp_indices=[0, 1], fig=fig, waterfall=True) ax = plt.gca() self.assertTrue(ax.is_waterfall())
def test_overplotting_supports_first_time_plot(self): # Note how we call overplot true first time round starting_fig = plt.figure() for _ in range(2): plot([self._test_ws], wksp_indices=[1], overplot=True) self.assertNotEqual(starting_fig, plt.figure(), "A new figure wasn't created")
def test_workspace_can_be_plotted_on_top_of_scripted_plots(self): fig = plt.figure() plt.plot([0, 1], [0, 1]) ws = self._test_ws plot([ws], wksp_indices=[1], fig=fig, overplot=True) ax = plt.gca() self.assertEqual(len(ax.lines), 2)
def test_1d_y_axes_label_distribution_workspace_auto_distribution_off(self): try: config['graph1d.autodistribution'] = 'Off' fig, ax = plt.subplots() funcs.plot(ax, self.ws2d_histo, 'rs', specNum=1) self.assertEqual(ax.get_ylabel(), "Counts ($\\AA$)$^{-1}$") finally: config['graph1d.autodistribution'] = 'On'
def test_title_preserved_when_workspace_plotted_on_scripted_plot(self): fig = plt.figure() plt.plot([0, 1], [0, 1]) plt.title("My Title") ws = self._test_ws plot([ws], wksp_indices=[1], fig=fig, overplot=True) ax = plt.gca() self.assertEqual("My Title", ax.get_title())
def test_different_line_colors_when_plotting_over_scripted_fig(self): fig = plt.figure() plt.plot([0, 1], [0, 1]) ws = self._test_ws plot([ws], wksp_indices=[1], fig=fig, overplot=True) ax = plt.gca() line_colors = [line.get_color() for line in ax.get_lines()] self.assertNotEqual(line_colors[0], line_colors[1])
def test_plot_gets_legend_visibility_from_ConfigService( self, mock_ConfigService): fig = plt.figure() plt.plot([0, 1], [0, 1]) ws = self._test_ws plot([ws], wksp_indices=[1], fig=fig, overplot=True) ax = plt.gca() mock_ConfigService.getString.assert_any_call('plots.ShowLegend') self.assertEqual(ax.get_legend().get_visible(), False)
def test_overplotting_onto_waterfall_plot_maintains_waterfall(self): fig = plt.figure() ws = self._test_ws plot([ws], wksp_indices=[0,1], fig=fig, waterfall=True) # Overplot one of the same lines. plot([ws], wksp_indices=[0], fig=fig, overplot=True) ax = plt.gca() # Check that the lines which would be the same in a non-waterfall plot are different. self.assertNotEqual(ax.get_lines()[0].get_xdata()[0], ax.get_lines()[2].get_xdata()[0]) self.assertNotEqual(ax.get_lines()[0].get_ydata()[0], ax.get_lines()[2].get_ydata()[0])
def test_grouped_workspaces_in_ads_unpacked(self): fig = plt.figure() plt.plot([0, 1], [0, 1]) ws1 = CloneWorkspace(self._test_ws, StoreInADS=True) ws2 = CloneWorkspace(self._test_ws, StoreInADS=True) group_list = [ws1, ws2] ws_group = GroupWorkspaces(group_list) plot([ws_group], wksp_indices=[1], fig=fig, overplot=True) ax = plt.gca() self.assertIn(ws1.name(), ax.tracked_workspaces) self.assertIn(ws2.name(), ax.tracked_workspaces)
def test_overplotting_onto_waterfall_plot_with_filled_areas_adds_another_filled_area(self): fig = plt.figure() ws = self._test_ws plot([ws], wksp_indices=[0, 1], fig=fig, waterfall=True) ax = plt.gca() ax.set_waterfall_fill(True) plot([ws], wksp_indices=[0], fig=fig, overplot=True) fills = [collection for collection in ax.collections if isinstance(collection, matplotlib.collections.PolyCollection)] self.assertEqual(len(fills), 3)
def test_waterfall_buttons_correctly_enabled_for_waterfall_plots( self, mock_qappthread): mock_qappthread.return_value = mock_qappthread fig, axes = plt.subplots(subplot_kw={'projection': 'mantid'}) ws = CreateSampleWorkspace() plot([ws], wksp_indices=[0, 1], fig=fig, waterfall=True) self.assertTrue(self._is_button_enabled(fig, 'waterfall_offset_amount')) self.assertTrue(self._is_button_enabled(fig, 'waterfall_reverse_order')) self.assertTrue(self._is_button_enabled(fig, 'waterfall_fill_area'))
def _compare_errorbar_labels_and_title(self): ws = self._test_ws ws.setYUnitLabel("MyLabel") ws.getAxis(0).setUnit("TOF") for distribution_ws in [True, False]: ws.setDistribution(distribution_ws) ax = plot([ws], wksp_indices=[1]).get_axes()[0] err_ax = plot([ws], wksp_indices=[1], errors=True).get_axes()[0] # Compare y-labels self.assertEqual(ax.get_ylabel(), err_ax.get_ylabel()) # Compare x-labels self.assertEqual(ax.get_xlabel(), err_ax.get_xlabel()) # Compare title self.assertEqual(ax.get_title(), err_ax.get_title())
def test_grouped_workspaces_not_in_ads(self): fig = plt.figure() plt.plot([0, 1], [0, 1]) num_plots = 3 ws_list = [] ws_group = WorkspaceGroup() for i in range(num_plots): ws = CloneWorkspace(self._test_ws, StoreInADS=False) ws_list.append(ws) ws_group.addWorkspace(ws) plot([ws_group], wksp_indices=[1], fig=fig, overplot=True) ax = plt.gca() self.assertEqual(len(ws_group) + 1, len(ax.lines)) self.assertEqual(len(ws_group) + 1, len(ax.lines))
def plotSpectrum(workspaces, indices=None, distribution=None, error_bars=False, type=None, window=None, clearWindow=None, waterfall=None, spectrum_nums=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 :param workspaces: Workspace/workspaces to plot as a string, workspace handle, list of strings or list of workspaces handles. :param indices: A single int or list of ints specifying the workspace indices to plot :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 workspace is a MatrixWorkspace histogram. :param error_bars: If true then error bars will be added for each curve :param type: curve style for plot it 1: scatter/dots otherwise line which is default :param window: If passed an existing plot then the plot will occur in that plot :param clearWindow: If true, and window set then the plot will be cleared before adding these curves :param waterfall: If true then a waterfall plot will be produced :param spectrum_nums: A single int or list of ints specifying the spectrum numbers to plot Cannot be used at the same time as indices """ _report_deprecated_parameter("distribution", distribution) plot_kwargs = {} if type==1: plot_kwargs["linestyle"] = "None" plot_kwargs["marker"] = "." return plot(_ensure_object_is_list(workspaces), wksp_indices=_ensure_object_is_list(indices), errors=error_bars, spectrum_nums=_ensure_object_is_list(spectrum_nums), waterfall = waterfall, fig=window, overplot=((window is not None) and not clearWindow), plot_kwargs=plot_kwargs)
def plotBin(workspaces, indices, error_bars=False, type=None, window=None, clearWindow=None, waterfall=None): """Create a 1D Plot of bin count vs spectrum in a workspace. This puts the spectrum number as the X variable, and the count in the particular bin # (in 'indices') as the Y value. If indices is a tuple or list, then several curves are created, one for each bin index. :param workspace or name of a workspace :param indices: bin number(s) to plot :param error_bars: If true then error bars will be added for each curve :param type: curve style for plot it 1: scatter/dots otherwise line, default :param window:If passed an existing plot then the plot will occur in that plot :param clearWindow: If true, and window set then the plot will be cleared before adding these curves :param waterfall: If true then a waterfall plot will be produced """ plot_kwargs = {"axis": MantidAxType.BIN} if type==1: plot_kwargs["linestyle"] = "None" plot_kwargs["marker"] = "." return plot(_ensure_object_is_list(workspaces), wksp_indices=_ensure_object_is_list(indices), errors=error_bars, plot_kwargs=plot_kwargs, fig = window, waterfall = waterfall, overplot = ((window is not None) and not clearWindow))
def plot(self, *args, **kwargs): """ If the **mantid** projection is chosen, it can be used the same as :py:meth:`matplotlib.axes.Axes.plot` 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.plot(workspace,'rs',specNum=1) #for workspaces ax.plot(x,y,'bo') #for arrays fig.show() For keywords related to workspaces, see :func:`plotfunctions.plot`. """ if helperfunctions.validate_args(*args): logger.debug('using plotfunctions') def _data_update(artists, workspace): # It's only possible to plot 1 line at a time from a workspace x, y, _, __ = plotfunctions._plot_impl(self, workspace, args, kwargs) artists[0].set_data(x, y) self.relim() self.autoscale() return artists return self.track_workspace_artist(args[0], plotfunctions.plot(self, *args, **kwargs), _data_update) else: return Axes.plot(self, *args, **kwargs)
def plot(self, *args, **kwargs): """ If the **mantid** projection is chosen, it can be used the same as :py:meth:`matplotlib.axes.Axes.plot` 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.plot(workspace,'rs',specNum=1) #for workspaces ax.plot(x,y,'bo') #for arrays fig.show() For keywords related to workspaces, see :func:`plotfunctions.plot`. """ 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): # It's only possible to plot 1 line at a time from a workspace if new_kwargs: x, y, _, __ = plotfunctions._plot_impl(self, workspace, args, new_kwargs) else: x, y, _, __ = plotfunctions._plot_impl(self, workspace, args, kwargs) artists[0].set_data(x, y) self.relim() if autoscale_on_update: self.autoscale() return artists workspace = args[0] spec_num = self.get_spec_number(workspace, kwargs) normalize_by_bin_width, kwargs = get_normalize_by_bin_width( workspace, self, **kwargs) is_normalized = normalize_by_bin_width or workspace.isDistribution() # If we are making the first plot on an axes object # i.e. self.lines is empty, axes has default ylim values. # Therefore we need to autoscale regardless of autoscale_on_update. if self.lines: # Otherwise set autoscale to autoscale_on_update. self.set_autoscaley_on(autoscale_on_update) artist = self.track_workspace_artist( workspace, plotfunctions.plot(self, *args, **kwargs), _data_update, spec_num, is_normalized) self.set_autoscaley_on(True) return artist else: return Axes.plot(self, *args, **kwargs)
def superplot_from_names(names, plot_kwargs): """ Open the superplot with a list of workspaces but no workspace indexes selected. :param names: A list of workspace names """ return plot(names, plot_kwargs=plot_kwargs, wksp_indices=[], superplot=True)
def test_1d_indices(self): fig, ax = plt.subplots() funcs.plot(ax, self.ws_MD_2d, indices=(slice(None), 0, 0)) funcs.plot(ax, self.ws_MD_2d, indices=(0, slice(None), 0)) funcs.plot(ax, self.ws_MD_2d, indices=(0, 0, slice(None))) self.assertRaises(AssertionError, funcs.plot, ax, self.ws_MD_2d, indices=(0, slice(None), slice(None))) self.assertRaises(AssertionError, funcs.plot, ax, self.ws_MD_2d)
def test_1d_slicepoint(self): fig, ax = plt.subplots() funcs.plot(ax, self.ws_MD_2d, slicepoint=(None, 0, 0)) funcs.plot(ax, self.ws_MD_2d, slicepoint=(0, None, 0)) funcs.plot(ax, self.ws_MD_2d, slicepoint=(0, 0, None)) self.assertRaises(AssertionError, funcs.plot, ax, self.ws_MD_2d, slicepoint=(0, None, None)) self.assertRaises(AssertionError, funcs.plot, ax, self.ws_MD_2d)
def test_superplot_bin_plot(self): fig = plt.gcf() fig.canvas.manager = mock.Mock() ws = CreateSampleWorkspace() plot([ws], wksp_indices=[], superplot=True, fig=fig, plot_kwargs={"axis": MantidAxType.BIN}) fig.canvas.manager.superplot.set_workspaces.assert_called_once() fig.canvas.manager.superplot.set_bin_mode.assert_called_once_with(True) fig.canvas.manager.reset_mock() plot([ws], wksp_indices=[], superplot=True, fig=fig, plot_kwargs={"axis": MantidAxType.SPECTRUM}) fig.canvas.manager.superplot.set_workspaces.assert_called_once() fig.canvas.manager.superplot.set_bin_mode.assert_called_once_with( False) fig.canvas.manager.reset_mock() plot([ws], wksp_indices=[], superplot=True, fig=fig, plot_kwargs={}) fig.canvas.manager.superplot.set_workspaces.assert_called_once() fig.canvas.manager.superplot.set_bin_mode.assert_called_once_with( False)
def test_1d_slicepoint(self): fig, ax = plt.subplots() funcs.plot(ax, self.ws_MD_2d, slicepoint=(None, 0, 0)) funcs.plot(ax, self.ws_MD_2d, slicepoint=(0, None, 0)) funcs.plot(ax, self.ws_MD_2d, slicepoint=(0, 0, None)) self.assertRaises(AssertionError, funcs.plot, ax, self.ws_MD_2d, slicepoint=(0, None, None)) self.assertRaises(AssertionError, funcs.plot, ax, self.ws_MD_2d)
def test_1d_indices(self): fig, ax = plt.subplots() funcs.plot(ax, self.ws_MD_2d, indices=(slice(None), 0, 0)) funcs.plot(ax, self.ws_MD_2d, indices=(0, slice(None), 0)) funcs.plot(ax, self.ws_MD_2d, indices=(0, 0, slice(None))) self.assertRaises(AssertionError, funcs.plot, ax, self.ws_MD_2d, indices=(0, slice(None), slice(None))) self.assertRaises(AssertionError, funcs.plot, ax, self.ws_MD_2d)
def plot_from_names(names, errors, overplot, fig=None, show_colorfill_btn=False): """ Given a list of names of workspaces, raise a dialog asking for the a selection of what to plot and then plot it. :param names: A list of workspace names :param errors: If true then error bars will be plotted on the points :param overplot: If true then the add to the current figure if one exists and it is a compatible figure :param fig: If not None then use this figure object to plot :return: The figure containing the plot or None if selection was cancelled """ workspaces = AnalysisDataService.Instance().retrieveWorkspaces( names, unrollGroups=True) try: selection = get_spectra_selection( workspaces, show_colorfill_btn=show_colorfill_btn, overplot=overplot) except Exception as exc: LOGGER.warning(format(str(exc))) selection = None if selection is None: return None elif selection == 'colorfill': return pcolormesh_from_names(names) return plot(selection.workspaces, spectrum_nums=selection.spectra, wksp_indices=selection.wksp_indices, errors=errors, overplot=overplot, fig=fig, tiled=selection.plot_type == selection.Tiled, waterfall=selection.plot_type == selection.Waterfall)
def plot(self, *args, **kwargs): """ If the **mantid** projection is chosen, it can be used the same as :py:meth:`matplotlib.axes.Axes.plot` 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.plot(workspace,'rs',specNum=1) #for workspaces ax.plot(x,y,'bo') #for arrays fig.show() For keywords related to workspaces, see :func:`plotfunctions.plot`. """ if helperfunctions.validate_args(*args): logger.debug('using plotfunctions') def _data_update(artists, workspace): # It's only possible to plot 1 line at a time from a workspace x, y, _, __ = plotfunctions._plot_impl(self, workspace, args, kwargs) artists[0].set_data(x, y) self.relim() self.autoscale() return artists workspace = args[0] spec_num = self._get_spec_number(workspace, kwargs) return self.track_workspace_artist( workspace, plotfunctions.plot(self, *args, **kwargs), _data_update, spec_num) else: return Axes.plot(self, *args, **kwargs)
def test_1d_log(self): fig, ax = plt.subplots() funcs.plot(ax, self.ws2d_histo, LogName='my_log') ax1 = ax.twiny() funcs.plot(ax1, self.ws2d_histo, LogName='my_log', FullTime=True)
def plot_from_names(names, errors, overplot, fig=None, show_colorfill_btn=False, advanced=False, superplot=False): """ Given a list of names of workspaces, raise a dialog asking for the a selection of what to plot and then plot it. :param names: A list of workspace names :param errors: If true then error bars will be plotted on the points :param overplot: If true then the add to the current figure if one exists and it is a compatible figure :param fig: If not None then use this figure object to plot :param advanced: If true then the advanced options will be shown in the spectra selector dialog. :return: The figure containing the plot or None if selection was cancelled """ # Get workspaces from ADS with names workspaces = AnalysisDataService.Instance().retrieveWorkspaces( names, unrollGroups=True) try: # Get selected spectra from all MatrixWorkspaces selection = get_spectra_selection( workspaces, show_colorfill_btn=show_colorfill_btn, overplot=overplot, advanced=advanced) except Exception as exc: LOGGER.warning(format(str(exc))) selection = None if selection is None: return None elif selection == 'colorfill': # plot mesh for color fill return pcolormesh_from_names(names) log_values = None if advanced: errors = selection.errors nums = selection.spectra if selection.spectra is not None else selection.wksp_indices if selection.log_name not in ['Workspace name', 'Workspace index']: log_values = [] counter = 0 for workspace in workspaces: for _ in nums: if selection.custom_log_values is not None: log_values.append( get_single_workspace_log_value( counter, log_values=selection.custom_log_values)) counter += 1 else: log_values.append( get_single_workspace_log_value( 1, matrix_ws=workspace, log_name=selection.log_name)) if selection.plot_type == selection.Surface or selection.plot_type == selection.Contour: if selection.spectra is not None: plot_index = workspaces[0].getIndexFromSpectrumNumber( selection.spectra[0]) else: plot_index = selection.wksp_indices[0] # import here to avoid circular import from mantid.plots.surfacecontourplots import plot as plot_surface_or_contour return plot_surface_or_contour(selection.plot_type, int(plot_index), selection.axis_name, selection.log_name, selection.custom_log_values, workspaces) else: return plot(selection.workspaces, spectrum_nums=selection.spectra, wksp_indices=selection.wksp_indices, errors=errors, overplot=overplot, fig=fig, tiled=selection.plot_type == selection.Tiled, waterfall=selection.plot_type == selection.Waterfall, log_name=selection.log_name, log_values=log_values, superplot=superplot)
def test_1d_plots(self): fig, ax = plt.subplots() funcs.plot(ax, self.ws2d_histo, 'rs', specNum=1) funcs.plot(ax, self.ws2d_histo, specNum=2, linewidth=6) funcs.plot(ax, self.ws_MD_1d, 'bo')
def test_1d_y_axes_label_distribution_workspace_auto_distribution_on(self): fig, ax = plt.subplots() funcs.plot(ax, self.ws2d_histo, 'rs', specNum=1) self.assertEqual(ax.get_ylabel(), "Counts ($\\AA$)$^{-1}$")
def test_1d_plots(self): fig, ax = plt.subplots() funcs.plot(ax, self.ws2d_histo, 'rs', specNum=1) funcs.plot(ax, self.ws2d_histo, specNum=2, linewidth=6) funcs.plot(ax, self.ws_MD_1d, 'bo')
def test_1d_log(self): fig, ax = plt.subplots() funcs.plot(ax, self.ws2d_histo, LogName='my_log') ax1 = ax.twiny() funcs.plot(ax1, self.ws2d_histo, LogName='my_log', FullTime=True)
def test_1d_x_axes_label_bin_plot(self): fig, ax = plt.subplots() funcs.plot(ax, self.ws2d_histo_non_dist, 'rs', specNum=1, axis=MantidAxType.BIN) self.assertEqual(ax.get_xlabel(), "Spectrum")
def test_1d_x_axes_label_spectrum_plot(self): fig, ax = plt.subplots() funcs.plot(ax, self.ws2d_histo_non_dist, 'rs', specNum=1, axis=MantidAxType.SPECTRUM) self.assertEqual(ax.get_xlabel(), "Wavelength ($\\AA$)")