Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit2236a2c

Browse files
committed
Clip RGB data to vaild range in Axes.imshow
1 parent7ee6499 commit2236a2c

File tree

6 files changed

+59
-7
lines changed

6 files changed

+59
-7
lines changed

‎doc/users/credits.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,7 @@ Yu Feng,
386386
Yunfei Yang,
387387
Yuri D'Elia,
388388
Yuval Langer,
389+
Zac Hatfield-Dodds,
389390
Zach Pincus,
390391
Zair Mubashar,
391392
alex,
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
`Axes.imshow` clips RGB values to the valid range
2+
-------------------------------------------------
3+
4+
When `Axes.imshow` is passed an RGB or RGBA value with out-of-range
5+
values, it now issues a warning and clips them to the valid range.
6+
The old behaviour, wrapping back in to the range, often hid outliers
7+
and made interpreting RGB images unreliable.

‎lib/matplotlib/axes/_axes.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5241,10 +5241,14 @@ def imshow(self, X, cmap=None, norm=None, aspect=None,
52415241
- MxNx3 -- RGB (float or uint8)
52425242
- MxNx4 -- RGBA (float or uint8)
52435243
5244-
The value for each component of MxNx3 and MxNx4 float arrays
5245-
should be in the range 0.0 to 1.0. MxN arrays are mapped
5246-
to colors based on the `norm` (mapping scalar to scalar)
5247-
and the `cmap` (mapping the normed scalar to a color).
5244+
MxN arrays are mapped to colors based on the `norm` (mapping
5245+
scalar to scalar) and the `cmap` (mapping the normed scalar to
5246+
a color).
5247+
5248+
Elements of RGB and RGBA arrays represent pixels of an MxN image.
5249+
All values should be in the range [0 .. 1] for floats or
5250+
[0 .. 255] for integers. Out-of-range values will be clipped to
5251+
these bounds.
52485252
52495253
cmap : `~matplotlib.colors.Colormap`, optional, default: None
52505254
If None, default to rc `image.cmap` value. `cmap` is ignored
@@ -5286,7 +5290,8 @@ def imshow(self, X, cmap=None, norm=None, aspect=None,
52865290
settings for `vmin` and `vmax` will be ignored.
52875291
52885292
alpha : scalar, optional, default: None
5289-
The alpha blending value, between 0 (transparent) and 1 (opaque)
5293+
The alpha blending value, between 0 (transparent) and 1 (opaque).
5294+
The ``alpha`` argument is ignored for RGBA input data.
52905295
52915296
origin : ['upper' | 'lower'], optional, default: None
52925297
Place the [0,0] index of the array in the upper left or lower left

‎lib/matplotlib/cm.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ def to_rgba(self, x, alpha=None, bytes=False, norm=True):
259259
xx= (xx*255).astype(np.uint8)
260260
elifxx.dtype==np.uint8:
261261
ifnotbytes:
262-
xx=xx.astype(float)/255
262+
xx=xx.astype(np.float32)/255
263263
else:
264264
raiseValueError("Image RGB array must be uint8 or "
265265
"floating point; found %s"%xx.dtype)

‎lib/matplotlib/image.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
frommathimportceil
1515
importos
16+
importlogging
1617

1718
importnumpyasnp
1819

@@ -34,6 +35,8 @@
3435
frommatplotlib.transformsimport (Affine2D,BboxBase,Bbox,BboxTransform,
3536
IdentityTransform,TransformedBbox)
3637

38+
_log=logging.getLogger(__name__)
39+
3740
# map interpolation strings to module constants
3841
_interpd_= {
3942
'none':_image.NEAREST,# fall back to nearest when not supported
@@ -621,6 +624,23 @@ def set_data(self, A):
621624
orself._A.ndim==3andself._A.shape[-1]in [3,4]):
622625
raiseTypeError("Invalid dimensions for image data")
623626

627+
ifself._A.ndim==3:
628+
# If the input data has values outside the valid range (after
629+
# normalisation), we issue a warning and then clip X to the bounds
630+
# - otherwise casting wraps extreme values, hiding outliers and
631+
# making reliable interpretation impossible.
632+
high=255ifnp.issubdtype(self._A.dtype,np.integer)else1
633+
ifself._A.min()<0orhigh<self._A.max():
634+
_log.warning(
635+
'Clipping input data to the valid range for imshow with '
636+
'RGB data ([0..1] for floats or [0..255] for integers).'
637+
)
638+
self._A=np.clip(self._A,0,high)
639+
# Cast unsupported integer types to uint8
640+
ifself._A.dtype!=np.uint8andnp.issubdtype(self._A.dtype,
641+
np.integer):
642+
self._A=self._A.astype(np.uint8)
643+
624644
self._imcache=None
625645
self._rgbacache=None
626646
self.stale=True

‎lib/matplotlib/tests/test_image.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -602,7 +602,7 @@ def test_minimized_rasterized():
602602
deftest_load_from_url():
603603
req=six.moves.urllib.request.urlopen(
604604
"http://matplotlib.org/_static/logo_sidebar_horiz.png")
605-
Z=plt.imread(req)
605+
plt.imread(req)
606606

607607

608608
@image_comparison(baseline_images=['log_scale_image'],
@@ -795,6 +795,25 @@ def test_imshow_no_warn_invalid():
795795
assertlen(warns)==0
796796

797797

798+
@pytest.mark.parametrize(
799+
'dtype', [np.dtype(s)forsin'u2 u4 i2 i4 i8 f4 f8'.split()])
800+
deftest_imshow_clips_rgb_to_valid_range(dtype):
801+
arr=np.arange(300,dtype=dtype).reshape((10,10,3))
802+
ifdtype.kind!='u':
803+
arr-=10
804+
ifdtype.kind=='f':
805+
arr=arr/255
806+
_,ax=plt.subplots()
807+
out=ax.imshow(arr).get_array()
808+
assertout.min()==0
809+
ifdtype.kind=='f':
810+
assertout.max()==1
811+
assertout.dtype.kind=='f'
812+
else:
813+
assertout.max==255
814+
assertout.dtype==np.uint8
815+
816+
798817
@image_comparison(baseline_images=['imshow_flatfield'],
799818
remove_text=True,style='mpl20',
800819
extensions=['png'])

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp