Skip to content

Commit 17e60a4

Browse files
committed
Explicit args and refactor Axes.margins
1 parent 213f399 commit 17e60a4

File tree

3 files changed

+69
-56
lines changed

3 files changed

+69
-56
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
Improved call signature for Axes.margins()
2+
------------------------------------------
3+
4+
:meth:`matplotlib.axes.Axes.margins` and :meth:`mpl_toolkits.mplot3d.Axes3D.margins`
5+
no longer accept arbitrary keywords. ``TypeError`` will therefore be raised
6+
if unknown kwargs are passed; previously they would be silently ignored.
7+
8+
If too many positional arguments are passed, ``TypeError`` will be raised
9+
instead of ``ValueError``, for consistency with other call-signature violations.
10+
11+
``Axes3D.margins`` now raises ``TypeError`` instead of emitting a deprecation
12+
warning if only two positional arguments are passed. To supply only ``x`` and
13+
``y`` margins, use keyword arguments.

lib/matplotlib/axes/_base.py

+25-21
Original file line numberDiff line numberDiff line change
@@ -2229,7 +2229,7 @@ def set_ymargin(self, m):
22292229
self._ymargin = m
22302230
self.stale = True
22312231

2232-
def margins(self, *args, **kw):
2232+
def margins(self, *margins, x=None, y=None, tight=True):
22332233
"""
22342234
Set or retrieve autoscaling margins.
22352235
@@ -2250,10 +2250,11 @@ def margins(self, *args, **kw):
22502250
margins(..., tight=False)
22512251
22522252
All three forms above set the xmargin and ymargin parameters.
2253-
All keyword parameters are optional. A single argument
2253+
All keyword parameters are optional. A single positional argument
22542254
specifies both xmargin and ymargin. The padding added to the end of
22552255
each interval is *margin* times the data interval. The *margin* must
2256-
be a float in the range [0, 1].
2256+
be a float in the range [0, 1]. Passing both positional and keyword
2257+
arguments for xmargin and/or ymargin is invalid.
22572258
22582259
The *tight* parameter is passed to :meth:`autoscale_view`
22592260
, which is executed after a margin is changed; the default here is
@@ -2267,27 +2268,30 @@ def margins(self, *args, **kw):
22672268
it is used in autoscaling.
22682269
22692270
"""
2270-
if not args and not kw:
2271+
if margins and x is not None and y is not None:
2272+
raise TypeError('Cannot pass both positional and keyword '
2273+
'arguments for x and/or y.')
2274+
elif len(margins) == 1:
2275+
x = y = margins[0]
2276+
elif len(margins) == 2:
2277+
x, y = margins
2278+
elif margins:
2279+
raise TypeError('Must pass a single positional argument for all '
2280+
'margins, or one for each margin (x, y).')
2281+
2282+
if x is None and y is None:
2283+
if tight is not True:
2284+
warnings.warn('ignoring tight=%r in get mode' % (tight,))
22712285
return self._xmargin, self._ymargin
22722286

2273-
tight = kw.pop('tight', True)
2274-
mx = kw.pop('x', None)
2275-
my = kw.pop('y', None)
2276-
if len(args) == 1:
2277-
mx = my = args[0]
2278-
elif len(args) == 2:
2279-
mx, my = args
2280-
elif len(args) > 2:
2281-
raise ValueError("more than two arguments were supplied")
2282-
if mx is not None:
2283-
self.set_xmargin(mx)
2284-
if my is not None:
2285-
self.set_ymargin(my)
2286-
2287-
scalex = (mx is not None)
2288-
scaley = (my is not None)
2287+
if x is not None:
2288+
self.set_xmargin(x)
2289+
if y is not None:
2290+
self.set_ymargin(y)
22892291

2290-
self.autoscale_view(tight=tight, scalex=scalex, scaley=scaley)
2292+
self.autoscale_view(
2293+
tight=tight, scalex=(x is not None), scaley=(y is not None)
2294+
)
22912295

22922296
def set_rasterization_zorder(self, z):
22932297
"""

lib/mpl_toolkits/mplot3d/axes3d.py

+31-35
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,7 @@ def set_zmargin(self, m):
384384
self._zmargin = m
385385
self.stale = True
386386

387-
def margins(self, *args, **kw):
387+
def margins(self, *margins, x=None, y=None, z=None, tight=True):
388388
"""
389389
Convenience method to set or retrieve autoscaling margins.
390390
@@ -404,8 +404,12 @@ def margins(self, *args, **kw):
404404
margins(..., tight=False)
405405
406406
All forms above set the xmargin, ymargin and zmargin
407-
parameters. All keyword parameters are optional. A single argument
408-
specifies xmargin, ymargin and zmargin. The *tight* parameter
407+
parameters. All keyword parameters are optional. A single
408+
positional argument specifies xmargin, ymargin and zmargin.
409+
Passing both positional and keyword arguments for xmargin,
410+
ymargin, and/or zmargin is invalid.
411+
412+
The *tight* parameter
409413
is passed to :meth:`autoscale_view`, which is executed after
410414
a margin is changed; the default here is *True*, on the
411415
assumption that when margins are specified, no additional
@@ -420,41 +424,33 @@ def margins(self, *args, **kw):
420424
.. versionadded :: 1.1.0
421425
This function was added, but not tested. Please report any bugs.
422426
"""
423-
if not args and not kw:
427+
if margins and x is not None and y is not None and z is not None:
428+
raise TypeError('Cannot pass both positional and keyword '
429+
'arguments for x, y, and/or z.')
430+
elif len(margins) == 1:
431+
x = y = z = margins[0]
432+
elif len(margins) == 3:
433+
x, y, z = margins
434+
elif margins:
435+
raise TypeError('Must pass a single positional argument for all '
436+
'margins, or one for each margin (x, y, z).')
437+
438+
if x is None and y is None and z is None:
439+
if tight is not True:
440+
warnings.warn('ignoring tight=%r in get mode' % (tight,))
424441
return self._xmargin, self._ymargin, self._zmargin
425442

426-
tight = kw.pop('tight', True)
427-
mx = kw.pop('x', None)
428-
my = kw.pop('y', None)
429-
mz = kw.pop('z', None)
430-
if not args:
431-
pass
432-
elif len(args) == 1:
433-
mx = my = mz = args[0]
434-
elif len(args) == 2:
435-
warnings.warn(
436-
"Passing exactly two positional arguments to Axes3D.margins "
437-
"is deprecated. If needed, pass them as keyword arguments "
438-
"instead", cbook.mplDeprecation)
439-
mx, my = args
440-
elif len(args) == 3:
441-
mx, my, mz = args
442-
else:
443-
raise ValueError(
444-
"Axes3D.margins takes at most three positional arguments")
445-
if mx is not None:
446-
self.set_xmargin(mx)
447-
if my is not None:
448-
self.set_ymargin(my)
449-
if mz is not None:
450-
self.set_zmargin(mz)
451-
452-
scalex = mx is not None
453-
scaley = my is not None
454-
scalez = mz is not None
443+
if x is not None:
444+
self.set_xmargin(x)
445+
if y is not None:
446+
self.set_ymargin(y)
447+
if z is not None:
448+
self.set_zmargin(z)
455449

456-
self.autoscale_view(tight=tight, scalex=scalex, scaley=scaley,
457-
scalez=scalez)
450+
self.autoscale_view(
451+
tight=tight, scalex=(x is not None), scaley=(y is not None),
452+
scalez=(z is not None)
453+
)
458454

459455
def autoscale(self, enable=True, axis='both', tight=None):
460456
"""

0 commit comments

Comments
 (0)