From be1d45a785f03d8363009d6a92607fbbf006457c Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Wed, 4 Sep 2024 17:09:02 +0100 Subject: [PATCH 1/2] Attempt at fix --- src/sas/qtgui/Plotting/Plotter.py | 67 ++++++++++++++++++++++++------- 1 file changed, 53 insertions(+), 14 deletions(-) diff --git a/src/sas/qtgui/Plotting/Plotter.py b/src/sas/qtgui/Plotting/Plotter.py index 17cb6be429..25e5834ed1 100644 --- a/src/sas/qtgui/Plotting/Plotter.py +++ b/src/sas/qtgui/Plotting/Plotter.py @@ -279,25 +279,20 @@ def plot(self, data=None, color=None, marker=None, hide_error=False, transform=T default_y_range = self.setRange.defaultYRange x_range = self.setRange.xrange() y_range = self.setRange.yrange() + elif isinstance(data, Data1D): # Get default ranges from data - # factors of .99 and 1.01 provides a small gap so end points not shown right at edge - pad_delta = 0.01 - default_x_range = self.ax.get_xlim() if not len(x) else ((1-pad_delta)*np.min(x), (1+pad_delta)*np.max(x)) + if self.has_nonempty_plots(): + x_range, y_range = self._plot_bounds() - # Need to make space for error bars - dy = data.view.dy - if not len(y): - default_y_range = self.ax.get_ylim() else: - if dy is None: - default_y_range = ((1-pad_delta) * np.min(y), (1+pad_delta) * np.max(y)) - else: - default_y_range = ((1-pad_delta)*np.min(np.array(y) - np.array(dy)), - (1+pad_delta)*np.max(np.array(y) + np.array(dy))) - x_range = default_x_range - y_range = default_y_range + + x_range = self.ax.get_xlim() + y_range = self.ax.get_ylim() + + default_x_range, default_y_range = x_range, y_range + modified = False else: # Use default ranges given by matplotlib @@ -328,6 +323,50 @@ def plot(self, data=None, color=None, marker=None, hide_error=False, transform=T # refresh canvas self.canvas.draw_idle() + def has_nonempty_plots(self) -> bool: + + for key in self.plot_dict: + if len(self.plot_dict[key].x) > 0: + return True + + return False + + def _plot_bounds(self, offset=0.01) -> tuple[tuple[float, float], tuple[float, float]]: + """ Get the appropriate bounds for the plots + + :param offset: add a small fraction of the absolute value of each end to each end + :returns: + """ + + min_scale = 1-offset + max_scale = 1+offset + + x_min, x_max = np.inf, -np.inf + y_min, y_max = np.inf, -np.inf + + for key in self.plot_dict: + + plot_data = self.plot_dict[key] + + if len(plot_data.x) > 0: + x_min = min(np.min(plot_data.x), x_min) + x_max = max(np.max(plot_data.x), x_max) + + if len(plot_data.y) > 0: + + dy = plot_data.view.dy + if dy is None: + y_min = min(np.min(plot_data.y), y_min) + y_max = max(np.max(plot_data.y), y_max) + else: + y_min = min(np.min(np.array(plot_data.y) - np.array(dy)), y_min) + y_max = max(np.max(np.array(plot_data.y) + np.array(dy)), y_max) + + return ((float(x_min*min_scale), + float(x_max*max_scale)), + (float(y_min*min_scale), + float(y_max*max_scale))) + def createContextMenu(self): """ From 0e4c19a40fa68a3f3914567dff79a2e29517efb1 Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Wed, 4 Sep 2024 17:33:14 +0100 Subject: [PATCH 2/2] Should work better now --- src/sas/qtgui/Plotting/Plotter.py | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/src/sas/qtgui/Plotting/Plotter.py b/src/sas/qtgui/Plotting/Plotter.py index 25e5834ed1..9d347d757f 100644 --- a/src/sas/qtgui/Plotting/Plotter.py +++ b/src/sas/qtgui/Plotting/Plotter.py @@ -331,15 +331,13 @@ def has_nonempty_plots(self) -> bool: return False - def _plot_bounds(self, offset=0.01) -> tuple[tuple[float, float], tuple[float, float]]: + def _plot_bounds(self, offset=0.05) -> tuple[tuple[float, float], tuple[float, float]]: """ Get the appropriate bounds for the plots :param offset: add a small fraction of the absolute value of each end to each end :returns: """ - min_scale = 1-offset - max_scale = 1+offset x_min, x_max = np.inf, -np.inf y_min, y_max = np.inf, -np.inf @@ -359,13 +357,22 @@ def _plot_bounds(self, offset=0.01) -> tuple[tuple[float, float], tuple[float, f y_min = min(np.min(plot_data.y), y_min) y_max = max(np.max(plot_data.y), y_max) else: - y_min = min(np.min(np.array(plot_data.y) - np.array(dy)), y_min) - y_max = max(np.max(np.array(plot_data.y) + np.array(dy)), y_max) - - return ((float(x_min*min_scale), - float(x_max*max_scale)), - (float(y_min*min_scale), - float(y_max*max_scale))) + try: + y_min = min(np.min(np.array(plot_data.y) - np.array(dy)), y_min) + y_max = max(np.max(np.array(plot_data.y) + np.array(dy)), y_max) + except ValueError: + # Ignore error term if it doesn't match y scale and causes an error + + y_min = min(np.min(plot_data.y), y_min) + y_max = max(np.max(plot_data.y), y_max) + + x_pad = offset*(x_max - x_min) + y_pad = offset*(y_max - y_min) + + return ((float(x_min - x_pad), + float(x_max + x_pad)), + (float(y_min - y_pad), + float(y_max + y_pad))) def createContextMenu(self):