From d95ff566a0577ec361fa91124fb5b280859de24b Mon Sep 17 00:00:00 2001 From: Drew Leonard Date: Thu, 12 Dec 2024 11:14:13 +0000 Subject: [PATCH 1/7] Catch ValueError in 1D animation update --- mpl_animators/wcs.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/mpl_animators/wcs.py b/mpl_animators/wcs.py index 770b1fe..0e93262 100644 --- a/mpl_animators/wcs.py +++ b/mpl_animators/wcs.py @@ -8,6 +8,7 @@ from mpl_animators.extern import modest_image from .base import ArrayAnimator +import warnings __all__ = ['ArrayAnimatorWCS'] @@ -277,8 +278,11 @@ def update_plot_1d(self, val, line, slider): # If we are not setting ylim globally then we set it per frame. if self.ylim == 'dynamic': - self.axes.set_ylim(float(self.data[self.frame_index].min()), - float(self.data[self.frame_index].max())) + try: + self.axes.set_ylim(float(self.data[self.frame_index].min()), + float(self.data[self.frame_index].max())) + except ValueError: + warnings.warn(UserWarning(f"No data found for data slice {self.frame_index} - cannot set ylim")) slider.cval = val def plot_start_image_2d(self, ax): From 2634be6fa42d9e6ff83b271e5ca210a68672ce1a Mon Sep 17 00:00:00 2001 From: Drew Leonard Date: Mon, 16 Dec 2024 15:26:57 +0000 Subject: [PATCH 2/7] Catch error setting clim in 2D plots --- mpl_animators/wcs.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/mpl_animators/wcs.py b/mpl_animators/wcs.py index 0e93262..a95c90f 100644 --- a/mpl_animators/wcs.py +++ b/mpl_animators/wcs.py @@ -319,7 +319,11 @@ def _get_2d_plot_limits(self): Get vmin, vmax of a data slice when clip_interval is specified. """ percent_limits = self.clip_interval.to('%').value - vmin, vmax = AsymmetricPercentileInterval(*percent_limits).get_limits(self.data_transposed) + try: + vmin, vmax = AsymmetricPercentileInterval(*percent_limits).get_limits(self.data_transposed) + except IndexError: + warnings.warn(UserWarning(f"No data found for data slice {self.frame_index} - cannot set vmin, vmax")) + vmin, vmax = 0, 0 return vmin, vmax def update_plot_2d(self, val, im, slider): From 273d2b9a47f0a48d3af3c5864e8c1f221462d7f3 Mon Sep 17 00:00:00 2001 From: Drew Leonard Date: Mon, 16 Dec 2024 16:03:06 +0000 Subject: [PATCH 3/7] Changelog --- changelog/73.trivial.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog/73.trivial.rst diff --git a/changelog/73.trivial.rst b/changelog/73.trivial.rst new file mode 100644 index 0000000..02566d0 --- /dev/null +++ b/changelog/73.trivial.rst @@ -0,0 +1 @@ +Catch errors when animating plots with missing data and replace them with warnings. From 037e5422088bb71669c40ad9ac306e1718ca1e62 Mon Sep 17 00:00:00 2001 From: Drew Leonard Date: Wed, 18 Dec 2024 11:25:28 +0000 Subject: [PATCH 4/7] Check for NaNs instead of catching ValueError --- mpl_animators/wcs.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/mpl_animators/wcs.py b/mpl_animators/wcs.py index a95c90f..48bbc49 100644 --- a/mpl_animators/wcs.py +++ b/mpl_animators/wcs.py @@ -278,11 +278,13 @@ def update_plot_1d(self, val, line, slider): # If we are not setting ylim globally then we set it per frame. if self.ylim == 'dynamic': - try: - self.axes.set_ylim(float(self.data[self.frame_index].min()), - float(self.data[self.frame_index].max())) - except ValueError: + vmin = float(self.data[self.frame_index].min()).compute() + vmax = float(self.data[self.frame_index].max()).compute() + if np.isnan(vmin) or np.isnan(vmax): warnings.warn(UserWarning(f"No data found for data slice {self.frame_index} - cannot set ylim")) + return + + self.axes.set_ylim(vmin, vmax) slider.cval = val def plot_start_image_2d(self, ax): From e55a81ce22cb2964ebce8812e8d618d14485f0df Mon Sep 17 00:00:00 2001 From: Drew Leonard Date: Wed, 18 Dec 2024 11:44:38 +0000 Subject: [PATCH 5/7] And again --- mpl_animators/wcs.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/mpl_animators/wcs.py b/mpl_animators/wcs.py index 48bbc49..99eadc4 100644 --- a/mpl_animators/wcs.py +++ b/mpl_animators/wcs.py @@ -321,11 +321,12 @@ def _get_2d_plot_limits(self): Get vmin, vmax of a data slice when clip_interval is specified. """ percent_limits = self.clip_interval.to('%').value - try: - vmin, vmax = AsymmetricPercentileInterval(*percent_limits).get_limits(self.data_transposed) - except IndexError: + if np.isnan(self.data_transposed).all().compute(): warnings.warn(UserWarning(f"No data found for data slice {self.frame_index} - cannot set vmin, vmax")) vmin, vmax = 0, 0 + else: + vmin, vmax = AsymmetricPercentileInterval(*percent_limits).get_limits(self.data_transposed) + return vmin, vmax def update_plot_2d(self, val, im, slider): From 8a6dcfd6ac55db0fb0a1d6b8aeafdf54a531b366 Mon Sep 17 00:00:00 2001 From: Drew Leonard Date: Wed, 18 Dec 2024 11:52:45 +0000 Subject: [PATCH 6/7] Well obviously that only works for dask arrays --- mpl_animators/wcs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mpl_animators/wcs.py b/mpl_animators/wcs.py index 99eadc4..3ed2997 100644 --- a/mpl_animators/wcs.py +++ b/mpl_animators/wcs.py @@ -321,7 +321,7 @@ def _get_2d_plot_limits(self): Get vmin, vmax of a data slice when clip_interval is specified. """ percent_limits = self.clip_interval.to('%').value - if np.isnan(self.data_transposed).all().compute(): + if np.isnan(self.data_transposed).all(): warnings.warn(UserWarning(f"No data found for data slice {self.frame_index} - cannot set vmin, vmax")) vmin, vmax = 0, 0 else: From 70e30cc027799acf5a7db77f4ca3c973e176d04d Mon Sep 17 00:00:00 2001 From: Drew Leonard Date: Wed, 18 Dec 2024 13:54:20 +0000 Subject: [PATCH 7/7] Use nanmin/nanmax in case some but not all of the data is nan --- mpl_animators/wcs.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mpl_animators/wcs.py b/mpl_animators/wcs.py index 3ed2997..f7bd546 100644 --- a/mpl_animators/wcs.py +++ b/mpl_animators/wcs.py @@ -278,8 +278,8 @@ def update_plot_1d(self, val, line, slider): # If we are not setting ylim globally then we set it per frame. if self.ylim == 'dynamic': - vmin = float(self.data[self.frame_index].min()).compute() - vmax = float(self.data[self.frame_index].max()).compute() + vmin = float(np.nanmin(self.data[self.frame_index])) + vmax = float(np.nanmax(self.data[self.frame_index])) if np.isnan(vmin) or np.isnan(vmax): warnings.warn(UserWarning(f"No data found for data slice {self.frame_index} - cannot set ylim")) return