Skip to content

Commit f50ab9a

Browse files
committed
ENH: allow image to interpolate post RGBA
1 parent c2946de commit f50ab9a

File tree

2 files changed

+37
-7
lines changed

2 files changed

+37
-7
lines changed

lib/matplotlib/axes/_axes.py

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5392,9 +5392,10 @@ def fill_betweenx(self, y, x1, x2=0, where=None,
53925392
#### plotting z(x, y): imshow, pcolor and relatives, contour
53935393
@_preprocess_data()
53945394
def imshow(self, X, cmap=None, norm=None, aspect=None,
5395-
interpolation=None, alpha=None, vmin=None, vmax=None,
5396-
origin=None, extent=None, *, filternorm=True, filterrad=4.0,
5397-
resample=None, url=None, **kwargs):
5395+
interpolation=None, interp_postrgba=False, alpha=None,
5396+
vmin=None, vmax=None, origin=None, extent=None, *,
5397+
filternorm=True, filterrad=4.0, resample=None, url=None,
5398+
**kwargs):
53985399
"""
53995400
Display data as an image, i.e., on a 2D regular raster.
54005401
@@ -5485,6 +5486,14 @@ def imshow(self, X, cmap=None, norm=None, aspect=None,
54855486
which can be set by *filterrad*. Additionally, the antigrain image
54865487
resize filter is controlled by the parameter *filternorm*.
54875488
5489+
interp_postrgba : bool, default: False
5490+
Whether the interpolation above is carried out before or after
5491+
the image data has been passed through the *norm* and colormapping.
5492+
This will cause the interpolation to take place in colorspace
5493+
rather than dataspace, which can be better for visual
5494+
anti-aliasing. Note that this is ignored if *X* is passed in as
5495+
RGB(A).
5496+
54885497
alpha : float or array-like, optional
54895498
The alpha blending value, between 0 (transparent) and 1 (opaque).
54905499
If *alpha* is an array, the alpha blending values are applied pixel
@@ -5582,9 +5591,9 @@ def imshow(self, X, cmap=None, norm=None, aspect=None,
55825591
if aspect is None:
55835592
aspect = rcParams['image.aspect']
55845593
self.set_aspect(aspect)
5585-
im = mimage.AxesImage(self, cmap, norm, interpolation, origin, extent,
5586-
filternorm=filternorm, filterrad=filterrad,
5587-
resample=resample, **kwargs)
5594+
im = mimage.AxesImage(self, cmap, norm, interpolation, interp_postrgba,
5595+
origin, extent, filternorm=filternorm,
5596+
filterrad=filterrad, resample=resample, **kwargs)
55885597

55895598
im.set_data(X)
55905599
im.set_alpha(alpha)

lib/matplotlib/image.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@ def __init__(self, ax,
234234
cmap=None,
235235
norm=None,
236236
interpolation=None,
237+
interp_postrgba=False,
237238
origin=None,
238239
filternorm=True,
239240
filterrad=4.0,
@@ -249,6 +250,7 @@ def __init__(self, ax,
249250
self.set_filternorm(filternorm)
250251
self.set_filterrad(filterrad)
251252
self.set_interpolation(interpolation)
253+
self.set_interp_postrgba(interp_postrgba)
252254
self.set_resample(resample)
253255
self.axes = ax
254256

@@ -393,7 +395,7 @@ def _make_image(self, A, in_bbox, out_bbox, clip_bbox, magnification=1.0,
393395
if not (A.ndim == 2 or A.ndim == 3 and A.shape[-1] in (3, 4)):
394396
raise ValueError(f"Invalid shape {A.shape} for image data")
395397

396-
if A.ndim == 2:
398+
if A.ndim == 2 and not self._interp_postrgba:
397399
# if we are a 2D array, then we are running through the
398400
# norm + colormap transformation. However, in general the
399401
# input data is not going to match the size on the screen so we
@@ -543,6 +545,9 @@ def _make_image(self, A, in_bbox, out_bbox, clip_bbox, magnification=1.0,
543545
):
544546
output = self.norm(resampled_masked)
545547
else:
548+
if A.ndim == 2: # _interp_postrgba is True
549+
self.norm.autoscale_None(A)
550+
A = self.to_rgba(A)
546551
if A.shape[2] == 3:
547552
A = _rgb_to_rgba(A)
548553
alpha = self._get_scalar_alpha()
@@ -775,6 +780,20 @@ def set_interpolation(self, s):
775780
self._interpolation = s
776781
self.stale = True
777782

783+
def set_interp_postrgba(self, s):
784+
"""
785+
Set whether interpolation happens after the image has been
786+
transformed to RGBA.
787+
788+
Parameters
789+
----------
790+
s : bool or None
791+
"""
792+
if s is None:
793+
s = False # placeholder for maybe having rcParam
794+
self._interp_postrgba = s
795+
self.stale = True
796+
778797
def can_composite(self):
779798
"""Return whether the image can be composited with its neighbors."""
780799
trans = self.get_transform()
@@ -887,6 +906,7 @@ def __init__(self, ax,
887906
cmap=None,
888907
norm=None,
889908
interpolation=None,
909+
interp_postrgba=False,
890910
origin=None,
891911
extent=None,
892912
filternorm=True,
@@ -902,6 +922,7 @@ def __init__(self, ax,
902922
cmap=cmap,
903923
norm=norm,
904924
interpolation=interpolation,
925+
interp_postrgba=interp_postrgba,
905926
origin=origin,
906927
filternorm=filternorm,
907928
filterrad=filterrad,

0 commit comments

Comments
 (0)