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

Skip to content

Commit b226b07

Browse files
committed
Make the signature of Axes.draw() consistent with Artist.draw().
... i.e. draw(renderer) instead of draw(renderer=None, inframe=False) (with a deprecation period).
1 parent 981b82e commit b226b07

File tree

4 files changed

+66
-18
lines changed

4 files changed

+66
-18
lines changed

doc/api/next_api_changes/deprecations.rst

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,3 +96,15 @@ colormapping such as ``scatter()`` and ``imshow()`` is deprecated.
9696
Inestead of ``norm=LogNorm(), vmin=min_val, vmax=max_val`` pass
9797
``norm=LogNorm(min_val, max_val)``. *vmin* and *vmax* should only be used
9898
without setting *norm*.
99+
100+
Signatures of `.Artist.draw` and `.Axes.draw`
101+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
102+
The *inframe* parameter to `.Axes.draw` is deprecated. Use
103+
`.Axes.redraw_in_frame` instead.
104+
105+
Not passing the *renderer* parameter to `.Axes.draw` is deprecated. Use
106+
``axes.draw_artist(axes)`` instead.
107+
108+
These changes make the signature of the ``draw`` (``artist.draw(renderer)``)
109+
method consistent across all artists; thus, additional parameters to
110+
`.Artist.draw` are deprecated.

lib/matplotlib/artist.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,10 @@ def allow_rasterization(draw):
2626
renderer.
2727
"""
2828

29-
# the axes class has a second argument inframe for its draw method.
29+
# Axes has a second (deprecated) argument inframe for its draw method.
30+
# args and kwargs are deprecated, but we don't wrap this in
31+
# cbook._delete_parameter for performance; the relevant deprecation
32+
# warning will be emitted by the inner draw() call.
3033
@wraps(draw)
3134
def draw_wrapper(artist, renderer, *args, **kwargs):
3235
try:
@@ -899,6 +902,8 @@ def set_agg_filter(self, filter_func):
899902
self._agg_filter = filter_func
900903
self.stale = True
901904

905+
@cbook._delete_parameter("3.3", "args")
906+
@cbook._delete_parameter("3.3", "kwargs")
902907
def draw(self, renderer, *args, **kwargs):
903908
"""
904909
Draw the Artist (and its children) using the given renderer.

lib/matplotlib/axes/_base.py

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from collections import OrderedDict
2+
from contextlib import ExitStack
23
import itertools
34
import logging
45
import math
@@ -2608,9 +2609,16 @@ def _update_title_position(self, renderer):
26082609

26092610
# Drawing
26102611
@martist.allow_rasterization
2612+
@cbook._delete_parameter(
2613+
"3.3", "inframe", alternative="Axes.redraw_in_frame()")
26112614
def draw(self, renderer=None, inframe=False):
26122615
# docstring inherited
26132616
if renderer is None:
2617+
cbook.warn_deprecated(
2618+
"3.3", message="Support for not passing the 'renderer' "
2619+
"paramater to Axes.draw() is deprecated since %(since)s and "
2620+
"will be removed %(removal)s. Use axes.draw_artist(axes) "
2621+
"instead.")
26142622
renderer = self.figure._cachedRenderer
26152623
if renderer is None:
26162624
raise RuntimeError('No renderer defined')
@@ -2691,7 +2699,7 @@ def draw_artist(self, a):
26912699
"""
26922700
This method can only be used after an initial draw which
26932701
caches the renderer. It is used to efficiently update Axes
2694-
data (axis ticks, labels, etc are not updated)
2702+
data (axis ticks, labels, etc are not updated).
26952703
"""
26962704
if self.figure._cachedRenderer is None:
26972705
raise AttributeError("draw_artist can only be used after an "
@@ -2702,12 +2710,17 @@ def redraw_in_frame(self):
27022710
"""
27032711
This method can only be used after an initial draw which
27042712
caches the renderer. It is used to efficiently update Axes
2705-
data (axis ticks, labels, etc are not updated)
2713+
data (axis ticks, labels, etc are not updated).
27062714
"""
27072715
if self.figure._cachedRenderer is None:
27082716
raise AttributeError("redraw_in_frame can only be used after an "
27092717
"initial draw which caches the renderer")
2710-
self.draw(self.figure._cachedRenderer, inframe=True)
2718+
with ExitStack() as stack:
2719+
for artist in [*self._get_axis_list(),
2720+
self.title, self._left_title, self._right_title]:
2721+
stack.push(artist.set_visible, artist.get_visible())
2722+
artist.set_visible(False)
2723+
self.draw(self.figure._cachedRenderer)
27112724

27122725
def get_renderer_cache(self):
27132726
return self.figure._cachedRenderer

lib/matplotlib/cbook/deprecation.py

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ def __repr__(self):
309309
_deprecated_parameter = _deprecated_parameter_class()
310310

311311

312-
def _delete_parameter(since, name, func=None):
312+
def _delete_parameter(since, name, func=None, **kwargs):
313313
"""
314314
Decorator indicating that parameter *name* of *func* is being deprecated.
315315
@@ -322,6 +322,8 @@ def _delete_parameter(since, name, func=None):
322322
such after the deprecation period has passed and the deprecated parameter
323323
is removed.
324324
325+
Additional kwargs are passed to `.warn_deprecated`.
326+
325327
Examples
326328
--------
327329
::
@@ -330,29 +332,45 @@ def func(used_arg, other_arg, unused, more_args): ...
330332
"""
331333

332334
if func is None:
333-
return functools.partial(_delete_parameter, since, name)
335+
return functools.partial(_delete_parameter, since, name, **kwargs)
334336

335337
signature = inspect.signature(func)
336338
assert name in signature.parameters, (
337339
f"Matplotlib internal error: {name!r} must be a parameter for "
338340
f"{func.__name__}()")
339-
func.__signature__ = signature.replace(parameters=[
340-
param.replace(default=_deprecated_parameter) if param.name == name
341-
else param
342-
for param in signature.parameters.values()])
341+
kind = signature.parameters[name].kind
342+
is_varargs = kind is inspect.Parameter.VAR_POSITIONAL
343+
is_varkwargs = kind is inspect.Parameter.VAR_KEYWORD
344+
if not is_varargs and not is_varkwargs:
345+
func.__signature__ = signature = signature.replace(parameters=[
346+
param.replace(default=_deprecated_parameter) if param.name == name
347+
else param
348+
for param in signature.parameters.values()])
343349

344350
@functools.wraps(func)
345-
def wrapper(*args, **kwargs):
346-
arguments = func.__signature__.bind(*args, **kwargs).arguments
351+
def wrapper(*inner_args, **inner_kwargs):
352+
arguments = signature.bind(*inner_args, **inner_kwargs).arguments
353+
if is_varargs and arguments[name]:
354+
warn_deprecated(
355+
since, message=f"Additional positional arguments to "
356+
f"{func.__name__}() are deprecated since %(since)s and "
357+
f"support for them will be removed %(removal)s.")
358+
elif is_varkwargs and arguments[name]:
359+
warn_deprecated(
360+
since, message=f"Additional keyword arguments to "
361+
f"{func.__name__}() are deprecated since %(since)s and "
362+
f"support for them will be removed %(removal)s.")
347363
# We cannot just check `name not in arguments` because the pyplot
348364
# wrappers always pass all arguments explicitly.
349-
if name in arguments and arguments[name] != _deprecated_parameter:
365+
elif name in arguments and arguments[name] != _deprecated_parameter:
350366
warn_deprecated(
351-
since, message=f"The {name!r} parameter of {func.__name__}() "
352-
f"is deprecated since Matplotlib {since} and will be removed "
353-
f"%(removal)s. If any parameter follows {name!r}, they "
354-
f"should be pass as keyword, not positionally.")
355-
return func(*args, **kwargs)
367+
since,
368+
name=repr(name),
369+
obj_type=f"parameter of {func.__name__}()",
370+
addendum=(f"If any parameter follows {name!r}, they should be "
371+
f"passed as keyword, not positionally."),
372+
**kwargs)
373+
return func(*inner_args, **inner_kwargs)
356374

357375
return wrapper
358376

0 commit comments

Comments
 (0)