-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Fixed an off-by-half-pixel bug in image resampling when using a nonaffine transform #30054
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
base: main
Are you sure you want to change the base?
Conversation
e0d192d
to
6729873
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On small change request but otherwise looks good to me. This is a very subtle bug - I'm incredibly curious about the story of how you found it!
Heh, I was hesitant to access There are a bunch of layers of private API between (Edit: As realized down below, I'll point out that this PR implicitly already has a test using public API, given that baseline images had to be updated. The plotting of an image using a log scale uses a nonaffine transform, and hence was affected by the bug. |
lib/matplotlib/tests/test_image.py
Outdated
[(np.array([[0.1, 0.3, 0.2]]), mpl._image.NEAREST, | ||
np.array([[0.1, 0.1, 0.1, 0.3, 0.3, 0.3, 0.3, 0.2, 0.2, 0.2]])), | ||
(np.array([[0.1, 0.3, 0.2]]), mpl._image.BILINEAR, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[(np.array([[0.1, 0.3, 0.2]]), mpl._image.NEAREST, | |
np.array([[0.1, 0.1, 0.1, 0.3, 0.3, 0.3, 0.3, 0.2, 0.2, 0.2]])), | |
(np.array([[0.1, 0.3, 0.2]]), mpl._image.BILINEAR, | |
[(np.array([[0.1, 0.3, 0.2]]), mimage.NEAREST, | |
np.array([[0.1, 0.1, 0.1, 0.3, 0.3, 0.3, 0.3, 0.2, 0.2, 0.2]])), | |
(np.array([[0.1, 0.3, 0.2]]), mimage.BILINEAR, |
These values are implemented in a private namespace, but are available in a public namespace (which is already imported directly)
This should also resolve the type hint problems
Fair enough. As I said, it is preferred but not strictly required. More that is was worth asking, especially with the mypy errors (for which my solution did not work btw, but the one provided above should). |
@ksunden Thanks for pointing out that |
I can mostly understand the line plots, but do you have an example of how this changes in an image itself? Possibly one that is rather low resolution so it is clear how the changes affect it. The test image that did change is a bit too high resolution to see clearly, I think. |
PR summary
This PR fixes a off-by-half-pixel bug in
matplotlib._image.resample()
when using a nonaffine transform. (This function is used internally when drawing an image artist.) The mesh for nonaffine transforms is mistakenly computed at the lower corners of pixels instead of the centers of pixels, which results in a half-pixel shift in the output. Here are illustrative plots and the generating script.Before this PR:

After this PR:

Script:
PR checklist