Skip to content

[ENH]: Ability to set imshow vmin/vmax with units #25062

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
dstansby opened this issue Jan 23, 2023 · 1 comment · May be fixed by #26104 or #27721
Open

[ENH]: Ability to set imshow vmin/vmax with units #25062

dstansby opened this issue Jan 23, 2023 · 1 comment · May be fixed by #26104 or #27721

Comments

@dstansby
Copy link
Member

Problem

Trying to use imshow with unit-ful data and setting vmin/vmax with units fails. It would be great if this was possible!

import matplotlib.pyplot as plt
import numpy as np

import pint
ureg = pint.UnitRegistry()
ureg.setup_matplotlib()

X, Y = np.meshgrid(np.linspace(-3, 3, 16), np.linspace(-3, 3, 16))
Z = (1 - X/2 + X**5 + Y**3) * np.exp(-X**2 - Y**2)
Z *= ureg.kg

fig, ax = plt.subplots()
ax.imshow(Z, vmin=1*ureg.kg, vmax=2*ureg.kg)
plt.show()
% python test.py
/Users/dstansby/github/matplotlib/lib/matplotlib/cbook.py:672: UnitStrippedWarning: The unit of the quantity is stripped when downcasting to ndarray.
  x = np.array(x, subok=True, copy=copy)
/Users/dstansby/github/matplotlib/lib/matplotlib/image.py:452: UnitStrippedWarning: The unit of the quantity is stripped when downcasting to ndarray.
  dv = np.float64(self.norm.vmax) - np.float64(self.norm.vmin)
/Users/dstansby/github/matplotlib/lib/matplotlib/image.py:453: UnitStrippedWarning: The unit of the quantity is stripped when downcasting to ndarray.
  vmid = np.float64(self.norm.vmin) + dv / 2
/Users/dstansby/github/matplotlib/lib/matplotlib/image.py:482: UnitStrippedWarning: The unit of the quantity is stripped when downcasting to ndarray.
  vrange = np.array([vmin, vmax], dtype=scaled_dtype)
Traceback (most recent call last):
  File "/Users/dstansby/mambaforge/envs/mpl/lib/python3.10/site-packages/pint/facets/plain/quantity.py", line 707, in __float__
    raise DimensionalityError(self._units, "dimensionless")
pint.errors.DimensionalityError: Cannot convert from 'kilogram' to 'dimensionless'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/Users/dstansby/github/matplotlib/lib/matplotlib/backend_bases.py", line 1223, in _on_timer
    ret = func(*args, **kwargs)
  File "/Users/dstansby/github/matplotlib/lib/matplotlib/backends/backend_macosx.py", line 68, in callback_func
    callback()
  File "/Users/dstansby/github/matplotlib/lib/matplotlib/backends/backend_macosx.py", line 88, in _draw_idle
    self.draw()
  File "/Users/dstansby/github/matplotlib/lib/matplotlib/backends/backend_macosx.py", line 50, in draw
    super().draw()
  File "/Users/dstansby/github/matplotlib/lib/matplotlib/backends/backend_agg.py", line 400, in draw
    self.figure.draw(self.renderer)
  File "/Users/dstansby/github/matplotlib/lib/matplotlib/artist.py", line 95, in draw_wrapper
    result = draw(artist, renderer, *args, **kwargs)
  File "/Users/dstansby/github/matplotlib/lib/matplotlib/artist.py", line 72, in draw_wrapper
    return draw(artist, renderer)
  File "/Users/dstansby/github/matplotlib/lib/matplotlib/figure.py", line 3116, in draw
    mimage._draw_list_compositing_images(
  File "/Users/dstansby/github/matplotlib/lib/matplotlib/image.py", line 131, in _draw_list_compositing_images
    a.draw(renderer)
  File "/Users/dstansby/github/matplotlib/lib/matplotlib/artist.py", line 72, in draw_wrapper
    return draw(artist, renderer)
  File "/Users/dstansby/github/matplotlib/lib/matplotlib/axes/_base.py", line 3066, in draw
    mimage._draw_list_compositing_images(
  File "/Users/dstansby/github/matplotlib/lib/matplotlib/image.py", line 131, in _draw_list_compositing_images
    a.draw(renderer)
  File "/Users/dstansby/github/matplotlib/lib/matplotlib/artist.py", line 72, in draw_wrapper
    return draw(artist, renderer)
  File "/Users/dstansby/github/matplotlib/lib/matplotlib/image.py", line 641, in draw
    im, l, b, trans = self.make_image(
  File "/Users/dstansby/github/matplotlib/lib/matplotlib/image.py", line 948, in make_image
    return self._make_image(self._A, bbox, transformed_bbox, clip,
  File "/Users/dstansby/github/matplotlib/lib/matplotlib/image.py", line 482, in _make_image
    vrange = np.array([vmin, vmax], dtype=scaled_dtype)
ValueError: setting an array element with a sequence.

Proposed solution

No response

@jklymak
Copy link
Member

jklymak commented Jan 23, 2023

Isn't this the same as #19476?

Edit: Well, close to $19476; I think it would disingenuous to pass the units through with no processing like is being done with Z here. Better would be to block Z from being passed through with units until we get unit support added to mappables (if we do).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants