Skip to content

Commit 319f35b

Browse files
authored
Merge pull request #17737 from anntzer/unboxstyle
Deprecate BoxStyle._Base.
2 parents 45494c5 + fc34d69 commit 319f35b

File tree

4 files changed

+156
-153
lines changed

4 files changed

+156
-153
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
BoxStyles are now called without passing the *mutation_aspect* parameter
2+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3+
Mutation aspect is now handled by the artist itself. Hence the
4+
*mutation_aspect* parameter of ``BoxStyle._Base.__call__`` is deprecated, and
5+
custom boxstyles should be implemented to not require this parameter (it can be
6+
left as a parameter defaulting to 1 for back-compatibility).

examples/userdemo/custom_boxstyle01.py

+7-21
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
# ``bbox=dict(boxstyle=custom_box_style, ...)`` to `.Axes.text`.
2626

2727

28-
def custom_box_style(x0, y0, width, height, mutation_size, mutation_aspect=1):
28+
def custom_box_style(x0, y0, width, height, mutation_size):
2929
"""
3030
Given the location and size of the box, return the path of the box around
3131
it.
@@ -38,11 +38,7 @@ def custom_box_style(x0, y0, width, height, mutation_size, mutation_aspect=1):
3838
Box location and size.
3939
mutation_size : float
4040
Mutation reference scale, typically the text font size.
41-
mutation_aspect
42-
Mutation aspect ratio.
4341
"""
44-
# We ignore mutation_aspect. This is okay in general.
45-
4642
# padding
4743
mypad = 0.3
4844
pad = mutation_size * mypad
@@ -66,19 +62,17 @@ def custom_box_style(x0, y0, width, height, mutation_size, mutation_aspect=1):
6662

6763

6864
###############################################################################
69-
# Alternatively, custom box styles can be implemented as subclasses of
70-
# ``matplotlib.patches.BoxStyle._Base``, by overriding the ``transmute``
71-
# method, as demonstrated below.
65+
# Likewise, custom box styles can be implemented as classes that implement
66+
# ``__call__``.
7267
#
73-
# The subclass can then be registered into the ``BoxStyle._style_list`` dict,
68+
# The classes can then be registered into the ``BoxStyle._style_list`` dict,
7469
# which allows specifying the box style as a string,
7570
# ``bbox=dict(boxstyle="registered_name,param=value,...", ...)``.
76-
#
77-
# Note that this approach relies on internal APIs and is therefore not
71+
# Note that this registration relies on internal APIs and is therefore not
7872
# officially supported.
7973

8074

81-
class MyStyle(BoxStyle._Base):
75+
class MyStyle:
8276
"""A simple box."""
8377

8478
def __init__(self, pad=0.3):
@@ -93,7 +87,7 @@ def __init__(self, pad=0.3):
9387
self.pad = pad
9488
super().__init__()
9589

96-
def transmute(self, x0, y0, width, height, mutation_size):
90+
def __call__(self, x0, y0, width, height, mutation_size):
9791
"""
9892
Given the location and size of the box, return the path of the box
9993
around it.
@@ -106,14 +100,6 @@ def transmute(self, x0, y0, width, height, mutation_size):
106100
Box location and size.
107101
mutation_size : float
108102
Reference scale for the mutation, typically the text font size.
109-
110-
Notes
111-
-----
112-
Unlike when defining the box style as a function (as in
113-
`custom_box_style`), here there is no *mutation_aspect* parameter.
114-
Matplotlib will first squeeze the box's y-axis by *mutation_aspect*
115-
before calling the `transmute` method, and then later reexpand the
116-
y-axis by the same amount.
117103
"""
118104
# padding
119105
pad = mutation_size * self.pad

lib/matplotlib/cbook/deprecation.py

+10-5
Original file line numberDiff line numberDiff line change
@@ -471,7 +471,8 @@ def _deprecate_method_override(method, obj, *, allow_empty=False, **kwargs):
471471
can always use ``__class__`` to refer to the class that is currently
472472
being defined.
473473
obj
474-
An object of the class where *method* is defined.
474+
Either an object of the class where *method* is defined, or a subclass
475+
of that class.
475476
allow_empty : bool, default: False
476477
Whether to allow overrides by "empty" methods without emitting a
477478
warning.
@@ -484,15 +485,19 @@ def empty(): pass
484485
def empty_with_docstring(): """doc"""
485486

486487
name = method.__name__
487-
bound_method = getattr(obj, name)
488-
if (bound_method != method.__get__(obj)
488+
bound_child = getattr(obj, name)
489+
bound_base = (
490+
method # If obj is a class, then we need to use unbound methods.
491+
if isinstance(bound_child, type(empty)) and isinstance(obj, type)
492+
else method.__get__(obj))
493+
if (bound_child != bound_base
489494
and (not allow_empty
490-
or (getattr(getattr(bound_method, "__code__", None),
495+
or (getattr(getattr(bound_child, "__code__", None),
491496
"co_code", None)
492497
not in [empty.__code__.co_code,
493498
empty_with_docstring.__code__.co_code]))):
494499
warn_deprecated(**{"name": name, "obj_type": "method", **kwargs})
495-
return bound_method
500+
return bound_child
496501
return None
497502

498503

0 commit comments

Comments
 (0)