From 50e5f766d5d0435f6268ac97e64d40d00d7491f1 Mon Sep 17 00:00:00 2001 From: Lee Johnston Date: Tue, 18 Aug 2020 10:11:42 -0500 Subject: [PATCH 1/3] Fix imshow to work with subclasses of ndarray. Fix #18077 --- lib/matplotlib/image.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/matplotlib/image.py b/lib/matplotlib/image.py index d6c2df8a48ca..2ef2226dc0bf 100644 --- a/lib/matplotlib/image.py +++ b/lib/matplotlib/image.py @@ -444,7 +444,7 @@ def _make_image(self, A, in_bbox, out_bbox, clip_bbox, magnification=1.0, # of over numbers. self.norm.autoscale_None(A) dv = np.float64(self.norm.vmax) - np.float64(self.norm.vmin) - vmid = self.norm.vmin + dv / 2 + vmid = np.float64(self.norm.vmin) + dv / 2 fact = 1e7 if scaled_dtype == np.float64 else 1e4 newmin = vmid - dv * fact if newmin < a_min: From e719a3c7484ae322ccfc52709fc2b83bc8441dce Mon Sep 17 00:00:00 2001 From: Lee Johnston Date: Tue, 18 Aug 2020 21:46:55 -0500 Subject: [PATCH 2/3] Add a test to check ndarray subclass handling --- lib/matplotlib/tests/test_image.py | 63 ++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/lib/matplotlib/tests/test_image.py b/lib/matplotlib/tests/test_image.py index 635d30900349..8332575d7c89 100644 --- a/lib/matplotlib/tests/test_image.py +++ b/lib/matplotlib/tests/test_image.py @@ -1124,3 +1124,66 @@ def test_exact_vmin(): @pytest.mark.flaky def test_https_imread_smoketest(): v = mimage.imread('https://matplotlib.org/1.5.0/_static/logo2.png') + + +# A basic ndarray subclass that implements a quantity +# It does not implement an entire unit system or all quantity math. +# There is just enough implemented to test handling of ndarray +# subclasses. +class QuantityND(np.ndarray): + def __new__(cls, input_array, units): + obj = np.asarray(input_array).view(cls) + obj.units = units + return obj + + def __array_finalize__(self, obj): + self.units = getattr(obj, "units", None) + + def __getitem__(self, item): + units = getattr(self, "units", None) + ret = super(QuantityND, self).__getitem__(item) + if isinstance(ret, QuantityND) or units is not None: + return QuantityND(ret, units) + return ret + + def __array_ufunc__(self, ufunc, method, *inputs, **kwargs): + func = getattr(ufunc, method) + if "out" in kwargs: + raise NotImplementedError + if len(inputs) == 1: + i0 = inputs[0] + unit = getattr(i0, "units", "dimensionless") + out_arr = func(np.asarray(i0), **kwargs) + elif len(inputs) == 2: + i0 = inputs[0] + i1 = inputs[1] + u0 = getattr(i0, "units", "dimensionless") + u1 = getattr(i1, "units", "dimensionless") + u0 = u1 if u0 is None else u0 + u1 = u0 if u1 is None else u1 + if ufunc in [np.add, np.subtract]: + if u0 != u1: + raise ValueError + unit = u0 + elif ufunc == np.multiply: + unit = f"{u0}*{u1}" + elif ufunc == np.divide: + unit = f"{u0}/({u1})" + else: + raise NotImplementedError + out_arr = func(i0.view(np.ndarray), i1.view(np.ndarray), **kwargs) + else: + raise NotImplementedError + if unit is None: + out_arr = np.array(out_arr) + else: + out_arr = QuantityND(out_arr, unit) + return out_arr + +def test_imshow_quantitynd(): + # generate a dummy ndarray subclass + arr = QuantityND(np.ones((2,2)), "m") + fig, ax = plt.subplots() + ax.imshow(arr) + # executing the draw should not raise an exception + fig.canvas.draw() \ No newline at end of file From a7bfe53fe0b92565750b32b37dc98f2041c6bed6 Mon Sep 17 00:00:00 2001 From: Lee Johnston Date: Tue, 18 Aug 2020 23:02:35 -0500 Subject: [PATCH 3/3] Improve test coverage of QuantityND --- lib/matplotlib/tests/test_image.py | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/lib/matplotlib/tests/test_image.py b/lib/matplotlib/tests/test_image.py index 8332575d7c89..1b9dd306a4dc 100644 --- a/lib/matplotlib/tests/test_image.py +++ b/lib/matplotlib/tests/test_image.py @@ -1143,7 +1143,7 @@ def __getitem__(self, item): units = getattr(self, "units", None) ret = super(QuantityND, self).__getitem__(item) if isinstance(ret, QuantityND) or units is not None: - return QuantityND(ret, units) + ret = QuantityND(ret, units) return ret def __array_ufunc__(self, ufunc, method, *inputs, **kwargs): @@ -1180,10 +1180,27 @@ def __array_ufunc__(self, ufunc, method, *inputs, **kwargs): out_arr = QuantityND(out_arr, unit) return out_arr + @property + def v(self): + return self.view(np.ndarray) + + +def test_quantitynd(): + q = QuantityND([1, 2], "m") + q0, q1 = q[:] + assert np.all(q.v == np.asarray([1, 2])) + assert q.units == "m" + assert np.all((q0 + q1).v == np.asarray([3])) + assert (q0 * q1).units == "m*m" + assert (q1 / q0).units == "m/(m)" + with pytest.raises(ValueError): + q0 + QuantityND(1, "s") + + def test_imshow_quantitynd(): # generate a dummy ndarray subclass - arr = QuantityND(np.ones((2,2)), "m") + arr = QuantityND(np.ones((2, 2)), "m") fig, ax = plt.subplots() ax.imshow(arr) # executing the draw should not raise an exception - fig.canvas.draw() \ No newline at end of file + fig.canvas.draw() 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