Skip to content

Commit

Permalink
MNT: Registered 3rd party scales do not need an axis parameter anymore
Browse files Browse the repository at this point in the history
First step of matplotlib#29349.
  • Loading branch information
timhoffm committed Dec 20, 2024
1 parent a18354a commit 87bfae6
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 11 deletions.
32 changes: 21 additions & 11 deletions lib/matplotlib/scale.py
Original file line number Diff line number Diff line change
Expand Up @@ -681,14 +681,19 @@ def limit_range_for_scale(self, vmin, vmax, minpos):


_scale_mapping = {
'linear': LinearScale,
'log': LogScale,
'symlog': SymmetricalLogScale,
'asinh': AsinhScale,
'logit': LogitScale,
'function': FuncScale,
'functionlog': FuncScaleLog,
}
# values temporarily changed from Scale to tuple
# (Scale, accepts_axis_parameter) so that we can handle
# both scales with and without the historic *axis* parameter
# as the first argument
# change back when the axis parameter is completely removed
'linear': (LinearScale, True),
'log': (LogScale, True),
'symlog': (SymmetricalLogScale, True),
'asinh': (AsinhScale, True),
'logit': (LogitScale, True),
'function': (FuncScale, True),
'functionlog': (FuncScaleLog, True),
}


def get_scale_names():
Expand All @@ -705,8 +710,11 @@ def scale_factory(scale, axis, **kwargs):
scale : {%(names)s}
axis : `~matplotlib.axis.Axis`
"""
scale_cls = _api.check_getitem(_scale_mapping, scale=scale)
return scale_cls(axis, **kwargs)
scale_cls, has_axis_parameter = _api.check_getitem(_scale_mapping, scale=scale)
if has_axis_parameter:
return scale_cls(axis, **kwargs)
else:
return scale_cls(**kwargs)


if scale_factory.__doc__:
Expand All @@ -723,7 +731,9 @@ def register_scale(scale_class):
scale_class : subclass of `ScaleBase`
The scale to register.
"""
_scale_mapping[scale_class.name] = scale_class
# Monkey-patch the signature information onto the scale so
has_axis_parameter = "axis" in inspect.signature(scale_class).parameters
_scale_mapping[scale_class.name] = (scale_class, has_axis_parameter)


def _get_scale_docs():
Expand Down
26 changes: 26 additions & 0 deletions lib/matplotlib/tests/test_scale.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
import io
import pytest

from lib.matplotlib.transforms import IdentityTransform


@check_figures_equal()
def test_log_scales(fig_test, fig_ref):
Expand Down Expand Up @@ -293,3 +295,27 @@ def test_bad_scale(self):
AsinhScale(axis=None, linear_width=-1)
s0 = AsinhScale(axis=None, )
s1 = AsinhScale(axis=None, linear_width=3.0)


def test_custom_scale_without_axis():
"""
Test that one can register and use custom scales that don't take an *axis* param.
"""
class CustomTransform(IdentityTransform):
pass

class CustomScale(mscale.ScaleBase):
def __init__(self):
self._transform = CustomTransform()

def get_transform(self):
return self._transform

try:
mscale.register_scale("custom", CustomScale)
fig, ax = plt.subplots()
ax.set_xscale('custom')
assert isinstance(ax.xaxis.get_transform(), CustomTransform)
finally:
# cleanup - there's no public unregister_scale()
del mscale._scale_mapping["custom"]

0 comments on commit 87bfae6

Please sign in to comment.