From 16f9778c6727531b4c06e407648c0c16e1a6ae3c Mon Sep 17 00:00:00 2001 From: Antony Lee Date: Wed, 6 Jul 2016 12:30:49 -0700 Subject: [PATCH 1/2] Don't convert vmin, vmax to floats. They may be float128's in which case precision would be lost; this can result in `Normalize` returning values (barely) outside of `[0, 1]`. (The cast to `float` was introduced in 28e1d2, referring to bug 2997687 on SF; it may be worth checking what it was about.) --- lib/matplotlib/colors.py | 5 +---- lib/matplotlib/tests/test_colors.py | 5 +++++ 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/matplotlib/colors.py b/lib/matplotlib/colors.py index 511f46d18710..0ffca3879df5 100644 --- a/lib/matplotlib/colors.py +++ b/lib/matplotlib/colors.py @@ -918,8 +918,6 @@ def __call__(self, value, clip=None): elif vmin > vmax: raise ValueError("minvalue must be less than or equal to maxvalue") else: - vmin = float(vmin) - vmax = float(vmax) if clip: mask = np.ma.getmask(result) result = np.ma.array(np.clip(result.filled(vmax), vmin, vmax), @@ -938,8 +936,7 @@ def __call__(self, value, clip=None): def inverse(self, value): if not self.scaled(): raise ValueError("Not invertible until scaled") - vmin = float(self.vmin) - vmax = float(self.vmax) + vmin, vmax = self.vmin, self.vmax if cbook.iterable(value): val = np.ma.asarray(value) diff --git a/lib/matplotlib/tests/test_colors.py b/lib/matplotlib/tests/test_colors.py index 072959eb8ff7..ee5a32564eee 100644 --- a/lib/matplotlib/tests/test_colors.py +++ b/lib/matplotlib/tests/test_colors.py @@ -194,6 +194,11 @@ def test_Normalize(): _scalar_tester(norm, vals) _mask_tester(norm, vals) + # Don't lose precision on longdoubles (float128 on Linux). + vals = np.array([1.2345678901, 9.8765432109], dtype=np.longdouble) + norm = mcolors.Normalize(vals.min(), vals.max()) + assert_array_equal(np.asarray(norm(vals)), [0, 1]) + def test_SymLogNorm(): """ From ff78a069bc1ad261ce4001d8347934e3995579b0 Mon Sep 17 00:00:00 2001 From: Antony Lee Date: Thu, 7 Jul 2016 19:13:51 -0700 Subject: [PATCH 2/2] Proper norm'ing of float128 scalars too. --- lib/matplotlib/colors.py | 23 +++++++---------------- lib/matplotlib/tests/test_colors.py | 7 ++++++- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/lib/matplotlib/colors.py b/lib/matplotlib/colors.py index 0ffca3879df5..73e0c8570794 100644 --- a/lib/matplotlib/colors.py +++ b/lib/matplotlib/colors.py @@ -880,22 +880,13 @@ def process_value(value): Experimental; we may want to add an option to force the use of float32. """ - if cbook.iterable(value): - is_scalar = False - result = np.ma.asarray(value) - if result.dtype.kind == 'f': - # this is overkill for lists of floats, but required - # to support pd.Series as input until we can reliable - # determine if result and value share memory in all cases - # (list, tuple, deque, ndarray, Series, ...) - result = result.copy() - elif result.dtype.itemsize > 2: - result = result.astype(float) - else: - result = result.astype(np.float32) - else: - is_scalar = True - result = np.ma.array([value]).astype(float) + is_scalar = not cbook.iterable(value) + if is_scalar: + value = [value] + dtype = np.min_scalar_type(value) + dtype = (np.float32 if dtype.itemsize <= 2 + else np.promote_types(dtype, float)) + result = np.ma.array(value, dtype=dtype, copy=True) return result, is_scalar def __call__(self, value, clip=None): diff --git a/lib/matplotlib/tests/test_colors.py b/lib/matplotlib/tests/test_colors.py index ee5a32564eee..986a5c9ca5cb 100644 --- a/lib/matplotlib/tests/test_colors.py +++ b/lib/matplotlib/tests/test_colors.py @@ -194,10 +194,15 @@ def test_Normalize(): _scalar_tester(norm, vals) _mask_tester(norm, vals) - # Don't lose precision on longdoubles (float128 on Linux). + # Don't lose precision on longdoubles (float128 on Linux): + # for array inputs... vals = np.array([1.2345678901, 9.8765432109], dtype=np.longdouble) norm = mcolors.Normalize(vals.min(), vals.max()) assert_array_equal(np.asarray(norm(vals)), [0, 1]) + # and for scalar ones. + eps = np.finfo(np.longdouble).resolution + norm = plt.Normalize(1, 1 + 100 * eps) + assert_equal(norm(1 + 50 * eps), .5) def test_SymLogNorm(): pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy