8000 MNT: Registered 3rd party scales do not need an axis parameter anymore · matplotlib/matplotlib@bb30bef · GitHub
[go: up one dir, main page]

Skip to content

Commit bb30bef

Browse files
committed
MNT: Registered 3rd party scales do not need an axis parameter anymore
First step of #29349.
1 parent a18354a commit bb30bef

File tree

3 files changed

+63
-2
lines changed

3 files changed

+63
-2
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
3rd party scales do not need to have an *axis* parameter anymore
2+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3+
4+
Since matplotlib 3.1 `PR 12831 <https://github.com/matplotlib/matplotlib/pull/12831>`_
5+
scales should be reusable and therefore independent of the Axis. Therefore the use of
6+
of the *axis* parameter in the ``__init__`` had been discouraged. However, that
7+
parameter was still necessary for API compatibility. This is no longer the case.
8+
9+
`.register_scale` now accepts scale classes with and without this parameter.
10+
3rd party scales can and should remove that parameter.

lib/matplotlib/scale.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -690,6 +690,9 @@ def limit_range_for_scale(self, vmin, vmax, minpos):
690690
'functionlog': FuncScaleLog,
691691
}
692692

693+
# caching of signature info
694+
_scale_has_axis_parameter = {}
695+
693696

694697
def get_scale_names():
695698
"""Return the names of the available scales."""
@@ -706,7 +709,19 @@ def scale_factory(scale, axis, **kwargs):
706709
axis : `~matplotlib.axis.Axis`
707710
"""
708711
scale_cls = _api.check_getitem(_scale_mapping, scale=scale)
709-
return scale_cls(axis, **kwargs)
712+
713+
# We support scales that may or may not have an initial *axis* parameter.
714+
# This information is cached, so that we do not need to inspect the signature
715+
# on every time we create a scale.
716+
if scale not in _scale_has_axis_parameter:
717+
_scale_has_axis_parameter[scale] = (
718+
"axis" in inspect.signature(scale_cls).parameters
719+
)
720+
721+
if _scale_has_axis_parameter[scale]:
722+
return scale_cls(axis, **kwargs)
723+
else:
724+
return scale_cls(**kwargs)
710725

711726

712727
if scale_factory.__doc__:

lib/matplotlib/tests/test_scale.py

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,12 @@
66
LogTransform, InvertedLogTransform,
77
SymmetricalLogTransform)
88
import matplotlib.scale as mscale
9-
from matplotlib.ticker import AsinhLocator, LogFormatterSciNotation
9+
from matplotlib.ticker import (
10+
AsinhLocator, AutoLocator, LogFormatterSciNotation,
11+
NullFormatter, NullLocator, ScalarFormatter
12+
)
1013
from matplotlib.testing.decorators import check_figures_equal, image_comparison
14+
from matplotlib.transforms import IdentityTransform
1115

1216
import numpy as np
1317
from numpy.testing import assert_allclose
@@ -293,3 +297,35 @@ def test_bad_scale(self):
293297
AsinhScale(axis=None, linear_width=-1)
294298
s0 = AsinhScale(axis=None, )
295299
s1 = AsinhScale(axis=None, linear_width=3.0)
300+
301+
302+
def test_custom_scale_without_axis():
303+
"""
304+
Test that one can register and use custom scales that don't take an *axis* param.
305+
"""
306+
class CustomTransform(IdentityTransform):
307+
pass
308+
309+
class CustomScale(mscale.ScaleBase):
310+
name = "custom"
311+
312+
def __init__(self):
313+
self._transform = CustomTransform()
314+
315+
def get_transform(self):
316+
return self._transform
317+
318+
def set_default_locators_and_formatters(self, axis):
319+
axis.set_major_locator(AutoLocator())
320+
axis.set_major_formatter(ScalarFormatter())
321+
axis.set_minor_locator(NullLocator())
322+
axis.set_minor_formatter(NullFormatter())
323+
324+
try:
325+
mscale.register_scale(CustomScale)
326+
fig, ax = plt.subplots()
327+
ax.set_xscale('custom')
328+
assert isinstance(ax.xaxis.get_transform(), CustomTransform)
329+
finally:
330+
# cleanup - there's no public unregister_scale()
331+
del mscale._scale_mapping["custom"]

0 commit comments

Comments
 (0)
0