Skip to content

Commit 35ccd4c

Browse files
committed
Adjust to favor the left input pixel for nearest-neighbor interpolation
This fixes a subtle issue where a resampled pixel falling exactly between two input pixels would normally round half up, but would also be rendered with rounding half up, resulting in the resampled pixel having the wrong value. The code now functionally rounds half down, which cancels out the effect of rendering rounding half up in these situations, and otherwise makes no difference.
1 parent dd24e05 commit 35ccd4c

1 file changed

Lines changed: 12 additions & 0 deletions

File tree

lib/matplotlib/image.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,12 +206,24 @@ def _resample(
206206
out = np.zeros(out_shape + data.shape[2:], data.dtype) # 2D->2D, 3D->3D.
207207
if resample is None:
208208
resample = image_obj.get_resample()
209+
210+
# When an output pixel falls exactly on the edge between two input pixels, the Agg
211+
# resampler will use the right input pixel as the nearest neighbor. We want the
212+
# left input pixel to be chosen instead, so we flip the supplied transform.
213+
if interpolation == 'nearest':
214+
transform += Affine2D().translate(-out.shape[1], -out.shape[0]).scale(-1, -1)
215+
209216
_image.resample(data, out, transform,
210217
_interpd_[interpolation],
211218
resample,
212219
alpha,
213220
image_obj.get_filternorm(),
214221
image_obj.get_filterrad())
222+
223+
# Because we flipped the supplied transform, we then flip the output image back.
224+
if interpolation == 'nearest':
225+
out = np.flip(out, axis=(0, 1))
226+
215227
return out
216228

217229

0 commit comments

Comments
 (0)