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

Skip to content

Commit 8ff9ac3

Browse files
committed
Make QuadMesh arguments with defaults keyword_only
1 parent 3bf56aa commit 8ff9ac3

File tree

4 files changed

+145
-17
lines changed

4 files changed

+145
-17
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
QuadMesh keyword only parameters
2+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3+
``QuadMesh`` parameters ``antialiased`` and ``shading`` will become
4+
keyword-only in a future version.

lib/matplotlib/axes/_axes.py

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6164,16 +6164,12 @@ def pcolormesh(self, *args, alpha=None, norm=None, cmap=None, vmin=None,
61646164

61656165
X, Y, C, shading = self._pcolorargs('pcolormesh', *args,
61666166
shading=shading, kwargs=kwargs)
6167-
Ny, Nx = X.shape
6168-
X = X.ravel()
6169-
Y = Y.ravel()
6170-
6171-
# convert to one dimensional arrays
6167+
coords = np.stack([X, Y], axis=-1)
6168+
# convert to one dimensional array
61726169
C = C.ravel()
6173-
coords = np.column_stack((X, Y)).astype(float, copy=False)
6174-
collection = mcoll.QuadMesh(Nx - 1, Ny - 1, coords,
6175-
antialiased=antialiased, shading=shading,
6176-
**kwargs)
6170+
6171+
collection = mcoll.QuadMesh(
6172+
coords, antialiased=antialiased, shading=shading, **kwargs)
61776173
snap = kwargs.get('snap', rcParams['pcolormesh.snap'])
61786174
collection.set_snap(snap)
61796175
collection.set_alpha(alpha)
@@ -6184,6 +6180,8 @@ def pcolormesh(self, *args, alpha=None, norm=None, cmap=None, vmin=None,
61846180

61856181
self.grid(False)
61866182

6183+
coords = coords.reshape(-1, 2) # flatten the grid structure; keep x, y
6184+
61876185
# Transform from native to data coordinates?
61886186
t = collection._transform
61896187
if (not isinstance(t, mtransforms.Transform) and
@@ -6360,7 +6358,7 @@ def pcolorfast(self, *args, alpha=None, norm=None, cmap=None, vmin=None,
63606358
else:
63616359
raise ValueError("C must be 2D or 3D")
63626360
collection = mcoll.QuadMesh(
6363-
nc, nr, coords, **qm_kwargs,
6361+
coords, **qm_kwargs,
63646362
alpha=alpha, cmap=cmap, norm=norm,
63656363
antialiased=False, edgecolors="none")
63666364
self.add_collection(collection, autolim=False)

lib/matplotlib/collections.py

Lines changed: 61 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,17 @@
99
line segments).
1010
"""
1111

12+
import inspect
1213
import math
1314
from numbers import Number
15+
import warnings
16+
1417
import numpy as np
1518

1619
import matplotlib as mpl
1720
from . import (_api, _path, artist, cbook, cm, colors as mcolors, docstring,
1821
hatch as mhatch, lines as mlines, path as mpath, transforms)
1922
from ._enums import JoinStyle, CapStyle
20-
import warnings
2123

2224

2325
# "color" is excluded; it is a compound setter, and its docstring differs
@@ -1991,21 +1993,73 @@ class QuadMesh(Collection):
19911993
19921994
*shading* may be 'flat', or 'gouraud'
19931995
"""
1994-
def __init__(self, meshWidth, meshHeight, coordinates,
1995-
antialiased=True, shading='flat', **kwargs):
1996-
super().__init__(**kwargs)
1996+
def __init__(self, *args, **kwargs):
1997+
# signature deprecation since="3.5": Change to new_sig after the
1998+
# deprecation has expired. Also remove setting __init__.__signature__.
1999+
old_sig = inspect.signature(
2000+
lambda meshWidth, meshHeight, coordinates,
2001+
antialiased=True, shading='flat', **kwargs: None)
2002+
new_sig = inspect.signature(
2003+
lambda coordinates, *,
2004+
antialiased=True, shading='flat', **kwargs: None)
2005+
try:
2006+
bound = new_sig.bind(*args, **kwargs)
2007+
except TypeError as exc:
2008+
try:
2009+
print(args, kwargs)
2010+
bound = old_sig.bind(*args, **kwargs)
2011+
except TypeError:
2012+
raise exc # the new_sig binding error makes more sense
2013+
# user passed in args using the old call convention
2014+
else:
2015+
bound.apply_defaults()
2016+
meshWidth = bound.arguments['meshWidth']
2017+
meshHeight = bound.arguments['meshHeight']
2018+
coordinates = bound.arguments['coordinates']
2019+
antialiased = bound.arguments['antialiased']
2020+
shading = bound.arguments['shading']
2021+
kwargs = bound.arguments['kwargs']
2022+
_api.warn_deprecated(
2023+
"3.5",
2024+
message="This usage of Quadmesh is deprecated: Parameters "
2025+
"meshWidth and meshHights will be removed; "
2026+
"coordinates must be 2D; all parameters except "
2027+
"coordinates will be keyword-only.")
2028+
super().__init__(**kwargs)
2029+
self._coordinates = np.asarray(coordinates, np.float64)\
2030+
.reshape((meshHeight + 1, meshWidth + 1, 2))
2031+
else:
2032+
bound.apply_defaults()
2033+
coordinates = bound.arguments['coordinates']
2034+
antialiased = bound.arguments['antialiased']
2035+
shading = bound.arguments['shading']
2036+
kwargs = bound.arguments['kwargs']
2037+
super().__init__(**kwargs)
2038+
self._coordinates = np.asarray(coordinates, np.float64)
2039+
shape = self._coordinates.shape
2040+
print('XX', self._coordinates.ndim, shape)
2041+
if (self._coordinates.ndim != 3 or shape[-1] != 2):
2042+
raise ValueError(
2043+
"coordinates must be a (N, M, 2) array-like, but got "
2044+
f"{shape}")
2045+
meshWidth = shape[1] - 1
2046+
meshHeight = shape[0] - 1
2047+
# end of signature deprecation code
2048+
19972049
self._meshWidth = meshWidth
19982050
self._meshHeight = meshHeight
1999-
# By converting to floats now, we can avoid that on every draw.
2000-
self._coordinates = np.asarray(coordinates, float).reshape(
2001-
(meshHeight + 1, meshWidth + 1, 2))
20022051
self._antialiased = antialiased
20032052
self._shading = shading
20042053

20052054
self._bbox = transforms.Bbox.unit()
20062055
self._bbox.update_from_data_xy(coordinates.reshape(
20072056
((meshWidth + 1) * (meshHeight + 1), 2)))
20082057

2058+
# Only needed during signature deprecation
2059+
__init__.__signature__ = inspect.signature(
2060+
lambda self, coordinates, *,
2061+
antialiased=True, shading='flat', **kwargs: None)
2062+
20092063
def get_paths(self):
20102064
if self._paths is None:
20112065
self.set_paths()

lib/matplotlib/tests/test_collections.py

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -714,6 +714,78 @@ def test_singleton_autolim():
714714
np.testing.assert_allclose(ax.get_xlim(), [-0.06, 0.06])
715715

716716

717+
@pytest.mark.parametrize('flat_ref, kwargs', [
718+
(True, {}),
719+
(False, {}),
720+
(True, dict(antialiased=False)),
721+
(False, dict(transform='__initialization_delayed__')),
722+
])
723+
@check_figures_equal(extensions=['png'])
724+
def test_quadmesh_deprecated_signature(
725+
fig_test, fig_ref, flat_ref, kwargs):
726+
# test that the new and old quadmesh signature produce the same results
727+
# remove when the old QuadMesh.__init__ signature expires (v3.5+2)
728+
from matplotlib.collections import QuadMesh
729+
730+
x = [0, 1, 2, 3.]
731+
y = [1, 2, 3.]
732+
X, Y = np.meshgrid(x, y)
733+
X += 0.2 * Y
734+
coords = np.stack([X, Y], axis=-1)
735+
assert coords.shape == (3, 4, 2)
736+
C = np.linspace(0, 2, 12).reshape(3, 4)
737+
738+
ax = fig_test.add_subplot()
739+
ax.set(xlim=(0, 5), ylim=(0, 4))
740+
if 'transform' in kwargs:
741+
kwargs['transform'] = mtransforms.Affine2D().scale(1.2) + ax.transData
742+
qmesh = QuadMesh(coords, **kwargs)
743+
qmesh.set_array(C)
744+
ax.add_collection(qmesh)
745+
746+
ax = fig_ref.add_subplot()
747+
ax.set(xlim=(0, 5), ylim=(0, 4))
748+
if 'transform' in kwargs:
749+
kwargs['transform'] = mtransforms.Affine2D().scale(1.2) + ax.transData
750+
with pytest.warns(MatplotlibDeprecationWarning):
751+
qmesh = QuadMesh(4 - 1, 3 - 1,
752+
coords.copy().reshape(-1, 2) if flat_ref else coords,
753+
**kwargs)
754+
qmesh.set_array(C.flatten() if flat_ref else C)
755+
ax.add_collection(qmesh)
756+
757+
758+
@check_figures_equal(extensions=['png'])
759+
def test_quadmesh_deprecated_positional(fig_test, fig_ref):
760+
# test that positional parameters are still accepted with the old signature
761+
# and work correctly
762+
# remove when the old QuadMesh.__init__ signature expires (v3.5+2)
763+
from matplotlib.collections import QuadMesh
764+
765+
x = [0, 1, 2, 3.]
766+
y = [1, 2, 3.]
767+
X, Y = np.meshgrid(x, y)
768+
X += 0.2 * Y
769+
coords = np.stack([X, Y], axis=-1)
770+
assert coords.shape == (3, 4, 2)
771+
coords_flat = coords.copy().reshape(-1, 2)
772+
C = np.linspace(0, 2, 12).reshape(3, 4)
773+
774+
ax = fig_test.add_subplot()
775+
ax.set(xlim=(0, 5), ylim=(0, 4))
776+
qmesh = QuadMesh(coords, antialiased=False, shading='gouraud')
777+
qmesh.set_array(C)
778+
ax.add_collection(qmesh)
779+
780+
ax = fig_ref.add_subplot()
781+
ax.set(xlim=(0, 5), ylim=(0, 4))
782+
with pytest.warns(MatplotlibDeprecationWarning):
783+
qmesh = QuadMesh(4 - 1, 3 - 1, coords.copy().reshape(-1, 2),
784+
False, 'gouraud')
785+
qmesh.set_array(C)
786+
ax.add_collection(qmesh)
787+
788+
717789
def test_quadmesh_set_array():
718790
x = np.arange(4)
719791
y = np.arange(4)

0 commit comments

Comments
 (0)