Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 981b82e

Browse files
authored
Merge pull request #15769 from timhoffm/fix-scatter-vmin-norm
scatter() should not rescale if norm is given
2 parents b83d9d6 + 0a2f082 commit 981b82e

File tree

5 files changed

+72
-30
lines changed

5 files changed

+72
-30
lines changed

doc/api/next_api_changes/deprecations.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,3 +88,11 @@ Setting :rc:`text.latex.preamble` or :rc:`pdf.preamble` to non-strings
8888
These rcParams should be set to string values. Support for None (meaning the
8989
empty string) and lists of strings (implicitly joined with newlines) is
9090
deprecated.
91+
92+
Parameters *norm* and *vmin*/*vmax* should not be used simultaneously
93+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
94+
Passing parameters *norm* and *vmin*/*vmax* simultaneously to functions using
95+
colormapping such as ``scatter()`` and ``imshow()`` is deprecated.
96+
Inestead of ``norm=LogNorm(), vmin=min_val, vmax=max_val`` pass
97+
``norm=LogNorm(min_val, max_val)``. *vmin* and *vmax* should only be used
98+
without setting *norm*.

lib/matplotlib/axes/_axes.py

Lines changed: 16 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4297,8 +4297,8 @@ def scatter(self, x, y, s=None, c=None, marker=None, cmap=None, norm=None,
42974297
vmin, vmax : scalar, default: None
42984298
*vmin* and *vmax* are used in conjunction with *norm* to normalize
42994299
luminance data. If None, the respective min and max of the color
4300-
array is used. *vmin* and *vmax* are ignored if you pass a *norm*
4301-
instance.
4300+
array is used.
4301+
It is deprecated to use *vmin*/*vmax* when *norm* is given.
43024302
43034303
alpha : scalar, default: None
43044304
The alpha blending value, between 0 (transparent) and 1 (opaque).
@@ -4419,11 +4419,7 @@ def scatter(self, x, y, s=None, c=None, marker=None, cmap=None, norm=None,
44194419
collection.set_array(c)
44204420
collection.set_cmap(cmap)
44214421
collection.set_norm(norm)
4422-
4423-
if vmin is not None or vmax is not None:
4424-
collection.set_clim(vmin, vmax)
4425-
else:
4426-
collection.autoscale_None()
4422+
collection._scale_norm(norm, vmin, vmax)
44274423

44284424
# Classic mode only:
44294425
# ensure there are margins to allow for the
@@ -4529,7 +4525,8 @@ def hexbin(self, x, y, C=None, gridsize=100, bins=None,
45294525
The colorbar range. If *None*, suitable min/max values are
45304526
automatically chosen by the `~.Normalize` instance (defaults to
45314527
the respective min/max values of the bins in case of the default
4532-
linear scaling). This is ignored if *norm* is given.
4528+
linear scaling).
4529+
It is deprecated to use *vmin*/*vmax* when *norm* is given.
45334530
45344531
alpha : float between 0 and 1, optional
45354532
The alpha blending value, between 0 (transparent) and 1 (opaque).
@@ -4773,11 +4770,7 @@ def reduce_C_function(C: array) -> float
47734770
collection.set_norm(norm)
47744771
collection.set_alpha(alpha)
47754772
collection.update(kwargs)
4776-
4777-
if vmin is not None or vmax is not None:
4778-
collection.set_clim(vmin, vmax)
4779-
else:
4780-
collection.autoscale_None()
4773+
collection._scale_norm(norm, vmin, vmax)
47814774

47824775
corners = ((xmin, ymin), (xmax, ymax))
47834776
self.update_datalim(corners)
@@ -5493,7 +5486,7 @@ def imshow(self, X, cmap=None, norm=None, aspect=None,
54935486
When using scalar data and no explicit *norm*, *vmin* and *vmax*
54945487
define the data range that the colormap covers. By default,
54955488
the colormap covers the complete value range of the supplied
5496-
data. *vmin*, *vmax* are ignored if the *norm* parameter is used.
5489+
data. It is deprecated to use *vmin*/*vmax* when *norm* is given.
54975490
54985491
origin : {'upper', 'lower'}, default: :rc:`image.origin`
54995492
Place the [0, 0] index of the array in the upper left or lower
@@ -5589,10 +5582,7 @@ def imshow(self, X, cmap=None, norm=None, aspect=None,
55895582
if im.get_clip_path() is None:
55905583
# image does not already have clipping set, clip to axes patch
55915584
im.set_clip_path(self.patch)
5592-
if vmin is not None or vmax is not None:
5593-
im.set_clim(vmin, vmax)
5594-
else:
5595-
im.autoscale_None()
5585+
im._scale_norm(norm, vmin, vmax)
55965586
im.set_url(url)
55975587

55985588
# update ax.dataLim, and, if autoscaling, set viewLim
@@ -5731,6 +5721,7 @@ def pcolor(self, *args, alpha=None, norm=None, cmap=None, vmin=None,
57315721
automatically chosen by the `~.Normalize` instance (defaults to
57325722
the respective min/max values of *C* in case of the default linear
57335723
scaling).
5724+
It is deprecated to use *vmin*/*vmax* when *norm* is given.
57345725
57355726
edgecolors : {'none', None, 'face', color, color sequence}, optional
57365727
The color of the edges. Defaults to 'none'. Possible values:
@@ -5867,8 +5858,7 @@ def pcolor(self, *args, alpha=None, norm=None, cmap=None, vmin=None,
58675858
collection.set_array(C)
58685859
collection.set_cmap(cmap)
58695860
collection.set_norm(norm)
5870-
collection.set_clim(vmin, vmax)
5871-
collection.autoscale_None()
5861+
collection._scale_norm(norm, vmin, vmax)
58725862
self.grid(False)
58735863

58745864
x = X.compressed()
@@ -5962,6 +5952,7 @@ def pcolormesh(self, *args, alpha=None, norm=None, cmap=None, vmin=None,
59625952
automatically chosen by the `~.Normalize` instance (defaults to
59635953
the respective min/max values of *C* in case of the default linear
59645954
scaling).
5955+
It is deprecated to use *vmin*/*vmax* when *norm* is given.
59655956
59665957
edgecolors : {'none', None, 'face', color, color sequence}, optional
59675958
The color of the edges. Defaults to 'none'. Possible values:
@@ -6081,8 +6072,7 @@ def pcolormesh(self, *args, alpha=None, norm=None, cmap=None, vmin=None,
60816072
collection.set_array(C)
60826073
collection.set_cmap(cmap)
60836074
collection.set_norm(norm)
6084-
collection.set_clim(vmin, vmax)
6085-
collection.autoscale_None()
6075+
collection._scale_norm(norm, vmin, vmax)
60866076

60876077
self.grid(False)
60886078

@@ -6196,6 +6186,7 @@ def pcolorfast(self, *args, alpha=None, norm=None, cmap=None, vmin=None,
61966186
automatically chosen by the `~.Normalize` instance (defaults to
61976187
the respective min/max values of *C* in case of the default linear
61986188
scaling).
6189+
It is deprecated to use *vmin*/*vmax* when *norm* is given.
61996190
62006191
alpha : scalar, default: None
62016192
The alpha blending value, between 0 (transparent) and 1 (opaque).
@@ -6278,10 +6269,9 @@ def pcolorfast(self, *args, alpha=None, norm=None, cmap=None, vmin=None,
62786269
self.add_image(im)
62796270
ret = im
62806271

6281-
if vmin is not None or vmax is not None:
6282-
ret.set_clim(vmin, vmax)
6283-
elif np.ndim(C) == 2: # C.ndim == 3 is RGB(A) so doesn't need scaling.
6284-
ret.autoscale_None()
6272+
if np.ndim(C) == 2: # C.ndim == 3 is RGB(A) so doesn't need scaling.
6273+
ret._scale_norm(norm, vmin, vmax)
6274+
62856275
if ret.get_clip_path() is None:
62866276
# image does not already have clipping set, clip to axes patch
62876277
ret.set_clip_path(self.patch)

lib/matplotlib/cm.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,27 @@ def __init__(self, norm=None, cmap=None):
184184
self.colorbar = None
185185
self.update_dict = {'array': False}
186186

187+
def _scale_norm(self, norm, vmin, vmax):
188+
"""
189+
Helper for initial scaling.
190+
191+
Used by public functions that create a ScalarMappable and support
192+
parameters *vmin*, *vmax* and *norm*. This makes sure that a *norm*
193+
will take precedence over *vmin*, *vmax*.
194+
195+
Note that this method does not set the norm.
196+
"""
197+
if vmin is not None or vmax is not None:
198+
self.set_clim(vmin, vmax)
199+
if norm is not None:
200+
cbook.warn_deprecated(
201+
"3.3",
202+
message="Passing parameters norm and vmin/vmax "
203+
"simultaneously is deprecated. Please pass "
204+
"vmin/vmax directly to the norm when creating it.")
205+
else:
206+
self.autoscale_None()
207+
187208
def to_rgba(self, x, alpha=None, bytes=False, norm=True):
188209
"""
189210
Return a normalized rgba array corresponding to *x*.

lib/matplotlib/tests/test_axes.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1001,6 +1001,19 @@ def test_imshow_clip():
10011001
ax.imshow(r, clip_path=clip_path)
10021002

10031003

1004+
@check_figures_equal(extensions=["png"])
1005+
def test_imshow_norm_vminvmax(fig_test, fig_ref):
1006+
"""Parameters vmin, vmax should be ignored if norm is given."""
1007+
a = [[1, 2], [3, 4]]
1008+
ax = fig_ref.subplots()
1009+
ax.imshow(a, vmin=0, vmax=5)
1010+
ax = fig_test.subplots()
1011+
with pytest.warns(MatplotlibDeprecationWarning,
1012+
match="Passing parameters norm and vmin/vmax "
1013+
"simultaneously is deprecated."):
1014+
ax.imshow(a, norm=mcolors.Normalize(-10, 10), vmin=0, vmax=5)
1015+
1016+
10041017
@image_comparison(['polycollection_joinstyle'], remove_text=True)
10051018
def test_polycollection_joinstyle():
10061019
# Bug #2890979 reported by Matthew West
@@ -1970,6 +1983,19 @@ def test_scatter_no_invalid_color(self, fig_test, fig_ref):
19701983
ax = fig_ref.subplots()
19711984
ax.scatter([0, 2], [0, 2], c=[1, 2], s=[1, 3], cmap=cmap)
19721985

1986+
@check_figures_equal(extensions=["png"])
1987+
def test_scatter_norm_vminvmax(self, fig_test, fig_ref):
1988+
"""Parameters vmin, vmax should be ignored if norm is given."""
1989+
x = [1, 2, 3]
1990+
ax = fig_ref.subplots()
1991+
ax.scatter(x, x, c=x, vmin=0, vmax=5)
1992+
ax = fig_test.subplots()
1993+
with pytest.warns(MatplotlibDeprecationWarning,
1994+
match="Passing parameters norm and vmin/vmax "
1995+
"simultaneously is deprecated."):
1996+
ax.scatter(x, x, c=x, norm=mcolors.Normalize(-10, 10),
1997+
vmin=0, vmax=5)
1998+
19731999
@check_figures_equal(extensions=["png"])
19742000
def test_scatter_single_point(self, fig_test, fig_ref):
19752001
ax = fig_test.subplots()

lib/matplotlib/tri/tripcolor.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -120,10 +120,7 @@ def tripcolor(ax, *args, alpha=1.0, norm=None, cmap=None, vmin=None,
120120
cbook._check_isinstance((Normalize, None), norm=norm)
121121
collection.set_cmap(cmap)
122122
collection.set_norm(norm)
123-
if vmin is not None or vmax is not None:
124-
collection.set_clim(vmin, vmax)
125-
else:
126-
collection.autoscale_None()
123+
collection._scale_norm(norm, vmin, vmax)
127124
ax.grid(False)
128125

129126
minx = tri.x.min()

0 commit comments

Comments
 (0)