From 9aa21fdf3d767c6ce6d5c348b4149c55a357f7fb Mon Sep 17 00:00:00 2001 From: Thomas Robitaille Date: Mon, 19 Mar 2018 19:29:28 +0000 Subject: [PATCH] Fix StateAtributeLimitsHelper if inf/-inf values are present in data --- CHANGES.md | 6 +++++ glue/core/state_objects.py | 17 ++++++------ glue/core/tests/test_state_objects.py | 37 +++++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 9 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index e221367f5..a0ee2dd35 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -90,6 +90,12 @@ v0.13.0 (unreleased) * Added a new selection mode that always forces the creation of a new subset. [#1525] +v0.12.6 (unreleased) +-------------------- + +* Fix a bug that caused viewer limits to be calculated incorrectly if + inf/-inf values were present in the data. [#1614] + v0.12.5 (unreleased) -------------------- diff --git a/glue/core/state_objects.py b/glue/core/state_objects.py index c663b0c8d..c94fb3ee2 100644 --- a/glue/core/state_objects.py +++ b/glue/core/state_objects.py @@ -339,24 +339,23 @@ def update_values(self, force=False, use_default_modifiers=False, **properties): self.set(lower=0.1, upper=1, percentile=percentile, log=log) return + # NOTE: we can't use np.nanmin/np.nanmax or nanpercentile below as + # they don't exclude inf/-inf + data_values = data_values[np.isfinite(data_values)] + if percentile == 100: if data_values.dtype.kind == 'M': lower = data_values.min() upper = data_values.max() else: - lower = np.nanmin(data_values) - upper = np.nanmax(data_values) + lower = np.min(data_values) + upper = np.max(data_values) else: - try: - lower = np.nanpercentile(data_values, exclude) - upper = np.nanpercentile(data_values, 100 - exclude) - except AttributeError: # Numpy < 1.9 - data_values = data_values[~np.isnan(data_values)] - lower = np.percentile(data_values, exclude) - upper = np.percentile(data_values, 100 - exclude) + lower = np.percentile(data_values, exclude) + upper = np.percentile(data_values, 100 - exclude) if self.data_component.categorical: lower = np.floor(lower - 0.5) + 0.5 diff --git a/glue/core/tests/test_state_objects.py b/glue/core/tests/test_state_objects.py index 1e06fe2e7..7cf0a7f9c 100644 --- a/glue/core/tests/test_state_objects.py +++ b/glue/core/tests/test_state_objects.py @@ -409,3 +409,40 @@ def test_state_serialization_datetime64(): state2 = clone(state1) assert state2.a == np.datetime64(100, 'D') + + +def test_nan_inf_minmax(): + + data = Data(x=[3, 1, -2, np.inf, np.nan], label='test_data') + + class SimpleState(State): + + layer = CallbackProperty() + comp = CallbackProperty() + lower = CallbackProperty() + upper = CallbackProperty() + percentile = CallbackProperty() + log = CallbackProperty() + + state = SimpleState() + + helper = StateAttributeLimitsHelper(state, attribute='comp', # noqa + lower='lower', upper='upper', + percentile='percentile', log='log') + + state.data = data + state.comp = data.id['x'] + + assert state.lower == -2 + assert state.upper == +3 + + state.log = True + + assert state.lower == +1 + assert state.upper == +3 + + state.log = False + state.percentile = 99 + + assert_allclose(state.lower, -1.97) + assert_allclose(state.upper, +2.98)