Fixed an off-by-half-pixel bug in image resampling when using a nonaffine transform (e.g., a log axis)#30054
Conversation
e0d192d to
6729873
Compare
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.
| [(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. |
|
Is any further action needed from me for this PR to be merged? Thanks! |
Co-authored-by: Elliott Sales de Andrade <quantum.analyst@gmail.com>
|
All green again |





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