diff --git a/lib/matplotlib/image.py b/lib/matplotlib/image.py index 0ab02c403d0d..ce08e2470d2f 100644 --- a/lib/matplotlib/image.py +++ b/lib/matplotlib/image.py @@ -452,6 +452,8 @@ def _make_image(self, A, in_bbox, out_bbox, clip_bbox, magnification=1.0, # Always copy, and don't allow array subtypes. A_scaled = np.array(A, dtype=scaled_dtype) + a_min = np.float64(a_min) + a_max = np.float64(a_max) # Clip scaled data around norm if necessary. This is necessary # for big numbers at the edge of float64's ability to represent # changes. Applying a norm first would be good, but ruins the diff --git a/lib/matplotlib/tests/test_colorbar.py b/lib/matplotlib/tests/test_colorbar.py index 74742d8c2369..cd7f6c223dd3 100644 --- a/lib/matplotlib/tests/test_colorbar.py +++ b/lib/matplotlib/tests/test_colorbar.py @@ -1238,3 +1238,48 @@ def test_colorbar_format_string_and_old(): plt.imshow([[0, 1]]) cb = plt.colorbar(format="{x}%") assert isinstance(cb._formatter, StrMethodFormatter) + + +def test_colorbar_log_units(): + class FakeQuantity(np.ndarray): + # this is a self-contained version of astropy.units.Quantity + # reduced to a bare minimum to reproduce + # https://github.com/astropy/astropy/issues/11306 + + def __new__(cls, value): + return np.array(value).view(cls) + + def __array_ufunc__(self, function, method, *inputs, **kwargs): + def to_value(q): + value = q.view(np.ndarray) + if value.shape: + return value + else: + return value[()] + + arrays = [to_value(q) for q in inputs] + result = super().__array_ufunc__(function, method, *arrays, **kwargs) + if function not in (np.minimum, np.maximum): + return result + else: + return self._new_view(result) + + def _new_view(self, obj): + obj = np.array(obj, copy=False, subok=True) + view = obj.view(FakeQuantity) + return view + + def __ne__(self, other): + return NotImplemented + + def __float__(self): + raise RuntimeError("boom") + + def item(self, *args): + return self._new_view(super().item(*args)) + + data = FakeQuantity([[1, 2], [3, 4]]) + fig, ax = plt.subplots() + im = ax.imshow(data, norm=LogNorm()) + fig.colorbar(im) + fig.canvas.draw() diff --git a/lib/matplotlib/transforms.py b/lib/matplotlib/transforms.py index 5003e2113930..4b0cd1cd035b 100644 --- a/lib/matplotlib/transforms.py +++ b/lib/matplotlib/transforms.py @@ -2853,15 +2853,15 @@ def nonsingular(vmin, vmax, expander=0.001, tiny=1e-15, increasing=True): if (not np.isfinite(vmin)) or (not np.isfinite(vmax)): return -expander, expander + # Expand vmin, vmax to float: if they were integer types, they can wrap + # around in abs (abs(np.int8(-128)) == -128) and vmax - vmin can overflow. + vmin, vmax = map(np.float64, (vmin, vmax)) + swapped = False if vmax < vmin: vmin, vmax = vmax, vmin swapped = True - # Expand vmin, vmax to float: if they were integer types, they can wrap - # around in abs (abs(np.int8(-128)) == -128) and vmax - vmin can overflow. - vmin, vmax = map(float, [vmin, vmax]) - maxabsvalue = max(abs(vmin), abs(vmax)) if maxabsvalue < (1e6 / tiny) * np.finfo(float).tiny: vmin = -expander
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: