8000 TST: add tests for up and down sampling for interpolation stage · matplotlib/matplotlib@0c5adf9 · GitHub
[go: up one dir, main page]

Skip to content

Commit 0c5adf9

Browse files
committed
TST: add tests for up and down sampling for interpolation stage
1 parent 2360c59 commit 0c5adf9

File tree

3 files changed

+67
-9
lines changed
  • lib/matplotlib
    • axes
    • < 8000 div id=":R3dtddab:" class="PRIVATE_TreeView-item-content prc-TreeView-TreeViewItemContent-f0r0b">tests

3 files changed

+67
-9
lines changed

lib/matplotlib/axes/_axes.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5791,11 +5791,14 @@ def imshow(self, X, cmap=None, norm=None, *, aspect=None,
57915791
which can be set by *filterrad*. Additionally, the antigrain image
57925792
resize filter is controlled by the parameter *filternorm*.
57935793
5794-
interpolation_stage : {'data', 'rgba'}, default: 'data'
5795-
If 'data', interpolation
5796-
is carried out on the data provided by the user. If 'rgba', the
5797-
interpolation is carried out after the colormapping has been
5798-
applied (visual interpolation).
5794+
interpolation_stage : {'antialiased', 'data', 'rgba'}, default: 'antialiased'
8000
5795+
If 'data', interpolation is carried out on the data provided by the user.
5796+
If 'rgba', the interpolation is carried out in RGBA-space after the
5797+
color-mapping has been applied (visual interpolation). If 'antialiased',
5798+
then 'rgba' is used if downsampling, or upsampling at a rate less than 3.
5799+
If upsampling at a higher rate, then 'data' is used.
5800+
See :doc:`/gallery/images_contours_and_fields/image_antialiasing` for
5801+
a discussion of image antialiasing.
57995802
58005803
alpha : float or array-like, optional
58015804
The alpha blending value, between 0 (transparent) and 1 (opaque).

lib/matplotlib/image.py

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -421,7 +421,21 @@ def _make_image(self, A, in_bbox, out_bbox, clip_bbox, magnification=1.0,
421421
if not unsampled:
422422
if not (A.ndim == 2 or A.ndim == 3 and A.shape[-1] in (3, 4)):
423423
raise ValueError(f"Invalid shape {A.shape} for image data")
424-
if A.ndim == 2 and self._interpolation_stage != 'rgba':
424+
425+
# if antialiased, this needs to change as window sizes
426+
# change:
427+
interpolation_stage = self._interpolation_stage
428+
if interpolation_stage == 'antialiased':
429+
pos = np.array([[0, 0], [A.shape[1], A.shape[0]]])
430+
disp = t.transform(pos)
431+
dispx = np.abs(np.diff(disp[:, 0])) / A.shape[1]
432+
dispy = np.abs(np.diff(disp[:, 1])) / A.shape[0]
433+
if (dispx < 3) or (dispy < 3):
434+
interpolation_stage = 'rgba'
435+
else:
436+
interpolation_stage = 'data'
437+
438+
if A.ndim == 2 and interpolation_stage == 'data':
425439
# if we are a 2D array, then we are running through the
426440
# nor 8000 m + colormap transformation. However, in general the
427441
# input data is not going to match the size on the screen so we
@@ -552,7 +566,7 @@ def _make_image(self, A, in_bbox, out_bbox, clip_bbox, magnification=1.0,
552566
cbook._setattr_cm(self.norm, vmin=s_vmin, vmax=s_vmax):
553567
output = self.norm(resampled_masked)
554568
else:
555-
if A.ndim == 2: # _interpolation_stage == 'rgba'
569+
if A.ndim == 2: # interpolation_stage == 'rgba'
556570
self.norm.autoscale_None(A)
557571
A = self.to_rgba(A)
558572
alpha = self._get_scalar_alpha()
@@ -787,12 +801,14 @@ def set_interpolation_stage(self, s):
787801
788802
Parameters
789803
----------
790-
s : {'data', 'rgba'} or None
804+
s : {'data', 'rgba', 'antialiased'} or None
791805
Whether to apply up/downsampling interpolation in data or RGBA
792806
space. If None, use :rc:`image.interpolation_stage`.
807+
If 'antialiased' we will check upsampling rate and if less
808+
than 3 then use 'rgba', otherwise use 'data'.
793809
"""
794810
s = mpl._val_or_rc(s, 'image.interpolation_stage')
795-
_api.check_in_list(['data', 'rgba'], s=s)
811+
_api.check_in_list(['data', 'rgba', 'antialiased'], s=s)
796812
self._interpolation_stage = s
797813
self.stale = True
798814

lib/matplotlib/tests/test_image.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1462,6 +1462,45 @@ def test_rgba_antialias():
14621462
cmap=cmap, vmin=-1.2, vmax=1.2)
14631463

14641464

1465+
@check_figures_equal(extensions=('png', ))
1466+
def test_upsample_interpolation_stage(fig_test, fig_ref):
1467+
"""
1468+
Show that interpolation_stage='antialiased' gives the same as 'data'
1469+
for upsampling.
1470+
"""
1471+
# Fixing random state for reproducibility. This non-standard seed
1472+
# gives red splotches for 'rgba'.
1473+
np.random.seed(19680801+9)
1474+
1475+
grid = np.random.rand(4, 4)
1476+
ax = fig_ref.subplots()
1477+
ax.imshow(grid, interpolation='bilinear', cmap='viridis',
1478+
interpolation_stage='data')
1479+
1480+
ax = fig_test.subplots()
1481+
ax.imshow(grid, interpolation='bilinear', cmap='viridis',
1482+
interpolation_stage='antialiased')
1483+
1484+
1485+
@check_figures_equal(extensions=('png', ))
1486+
def test_downsample_interpolation_stage(fig_test, fig_ref):
1487+
"""
1488+
Show that interpolation_stage='antialiased' gives the same as 'rgba'
1489+
for downsampling.
1490+
"""
1491+
# Fixing random state for reproducibility
1492+
np.random.seed(19680801)
1493+
1494+
grid = np.random.rand(4000, 4000)
1495+
ax = fig_ref.subplots()
1496+
ax.imshow(grid, interpolation='antialiased', cmap='viridis',
1497+
interpolation_stage='rgba')
1498+
1499+
ax = fig_test.subplots()
1500+
ax.imshow(grid, interpolation='antialiased', cmap='viridis',
1501+
interpolation_stage='antialiased')
1502+
1503+
14651504
def test_rc_interpolation_stage():
14661505
for val in ["data", "rgba"]:
14671506
with mpl.rc_context({"image.interpolation_stage": val}):

0 commit comments

Comments
 (0)
0