-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
QuadMesh.get_clim changed behavior in 3.3.0rc1 #17703
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
Comments
Ah, it looks like in some cases we either called Adding I don't see a way to put a deprecation warning on this behavior without being too annoying so I think out options are
While writing this out I am various points had convinced my self that all 3 options were the "best" option ;) 1 / 3 get us consistency but break different directions on if we should resolve the "auto" limit as soon as possible or as late as possible 2 gets us a little change in behavior as possible, but means that the early/late resolution varies by plotting method / Aritst. |
And thank you @MaozGelbart for testing the RC :) |
We discussed this on the call and noted that if you pass nothing we call |
This turned into a rabbit hole of complexity. This is the current state for everything on 3.3
I am more convinced that we want to change it so in all cases when the a) pass in dummy data + one of vmin or vmax I am hoping this is rare because it seems like it is quite brittle. This is what I was using to play with this: import functools
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
import numpy as np
class ForgivingNorm(mcolors.Normalize):
@functools.wraps(mcolors.Normalize.__call__)
def __call__(self, value, *args, **kwargs):
try:
return super().__call__(value, *args, **kwargs)
except ValueError:
if self.vmin < self.vmax:
# not sure why we are here?!
raise
# we are now here because self.vmax < self.vmin
# normally this is something we raise an exception and kill
# the draw on, but we want this to work
result, is_scalar = self.process_value(value)
result = np.ma.array(result.data, mask=True, copy=False)
if is_scalar:
result = result[0]
return result
def __repr__(self):
return f'<ForgivingNorm(vmin={self.vmin}, vmax={self.vmax})>'
# monkey patch for reasons
mcolors.Normalize = ForgivingNorm
zero_data = np.zeros((5, 5))
ramp_data = np.arange(25).reshape(5, 5) + .5
def run_test(zero_data, ramp_data, *, early_autoscale_None, make_norm):
fig, ax_arr = plt.subplots(2, 2, squeeze=False)
[[ax1, ax2], [ax3, ax4]] = ax_arr
im_dict = {}
for j, (ax, kwargs) in enumerate(
zip(ax_arr.ravel(), ({}, {"vmin": 10}, {"vmax": 15}, {"vmin": 10, "vmax": 15}))
):
if make_norm:
kwargs = {'norm': ForgivingNorm(**kwargs)}
im_dict[j] = im = ax.imshow(zero_data, **kwargs)
if early_autoscale_None:
im.autoscale_None()
a = f'pre: {im.get_clim()}'
im.set_data(ramp_data)
# this will happen eventually during the rendering, do it here
# to capture the result
im.autoscale_None()
b = f'post: {im.get_clim()}'
ax.set_title(f"{kwargs=}\n{a} {b}")
fig.suptitle(f"{early_autoscale_None=} {make_norm=}")
return fig, ax_arr, im_dict |
Bug report
Bug summary
QuadMesh.get_clim()
is documented as:Without
vmin
orvmax
arguments topcolormesh
, this returns the data minimal and maximal values. However in the presence of only one ofvmin
orvmax
, a change occurred between 3.2.2 and 3.3.0rc1. In 3.3.0rc1 it returns the input vmin and vmax, though only one of them was specified. The provided examples also happens (with slight output changes) for settingvmax
instead of vmin.Code for reproduction
Actual outcome
Expected outcome
Matplotlib version
print(matplotlib.get_backend())
): MacOSXInstalled using pip
The text was updated successfully, but these errors were encountered: