Skip to content

Make Scale axis parameter handling more flexible#31621

Open
QuLogic wants to merge 1 commit intomatplotlib:mainfrom
QuLogic:axis-scale
Open

Make Scale axis parameter handling more flexible#31621
QuLogic wants to merge 1 commit intomatplotlib:mainfrom
QuLogic:axis-scale

Conversation

@QuLogic
Copy link
Copy Markdown
Member

@QuLogic QuLogic commented May 6, 2026

PR summary

Instead of checking the types ourselves, try to bind the old signature, and if possible, use it. Otherwise, try to use the new signature. This is similar to _api.select_matching_signature without needing to write a callable for each signature.

Note there are some invalid call signatures that might error in less than clear ways, but they already did so, and I did not attempt to make these clearer. (For example, FuncScale(axis) will try to use the Axis as functions and fail to unpack it as a tuple, but this was true with the original _make_axis_parameter_optional.)

Closes #31590

AI Disclosure

None

PR checklist

@QuLogic QuLogic added this to the v3.11.0 milestone May 6, 2026
@QuLogic QuLogic added the Release critical For bugs that make the library unusable (segfaults, incorrect plots, etc) and major regressions. label May 6, 2026
@QuLogic
Copy link
Copy Markdown
Member Author

QuLogic commented May 6, 2026

Also wondering if we should update the type hints to drop axis?

Copy link
Copy Markdown
Member

@timhoffm timhoffm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What previously worked was passing multiple parameters positionally LogitScale(axis, 'mask'). In rare cases, we one cannot just leave out the axis parameter. For FuncScale(functions) this works because functions has no default and thus the first bind attept fails, but for LogitScale('mask') this wrongly binds 'mask' to axis and keeps using the default non_positive='mask'.

That may be bearable as it only affects the new call pattern. Possibly we should advise users to always pass scale parameters by name. We already do this in scale_factory().

In theory we should _make_keyword_only to all scale parameters, but I cannot wrap my head around whether that would badly interact with _make_axis_parameter_optional right now.

Type stubs: I would only update them when we start deprecating using the axis parameter, which we intentionally do not do yet to smoothen the transition.

Comment thread lib/matplotlib/tests/test_scale.py Outdated
Comment on lines +32 to +50
FuncScale(None, (lambda x: x, lambda x: x))
FuncScale(None, functions=(lambda x: x, lambda x: x))
LogitScale(None)
LogitScale(None, 'clip')
LogitScale(None, nonpositive='clip')
LogitScale(None, use_overline=True)
AsinhScale(None)
AsinhScale(None, linear_width=2)
AsinhScale(None, base=3)
AsinhScale(None, subs=[2, 6])
# Old signature with axis as keyword.
FuncScale(axis=None, functions=(lambda x: x, lambda x: x))
LogitScale(axis=None)
LogitScale(axis=None, nonpositive='clip')
LogitScale(axis=None, use_overline=True)
AsinhScale(axis=None)
AsinhScale(axis=None, linear_width=2)
AsinhScale(axis=None, base=3)
AsinhScale(axis=None, subs=[2, 6])
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
FuncScale(None, (lambda x: x, lambda x: x))
FuncScale(None, functions=(lambda x: x, lambda x: x))
LogitScale(None)
LogitScale(None, 'clip')
LogitScale(None, nonpositive='clip')
LogitScale(None, use_overline=True)
AsinhScale(None)
AsinhScale(None, linear_width=2)
AsinhScale(None, base=3)
AsinhScale(None, subs=[2, 6])
# Old signature with axis as keyword.
FuncScale(axis=None, functions=(lambda x: x, lambda x: x))
LogitScale(axis=None)
LogitScale(axis=None, nonpositive='clip')
LogitScale(axis=None, use_overline=True)
AsinhScale(axis=None)
AsinhScale(axis=None, linear_width=2)
AsinhScale(axis=None, base=3)
AsinhScale(axis=None, subs=[2, 6])
# testing with None is sufficient as detection is purely based on the
# signature structure, no type information is in involved
axis=None
FuncScale(axis, (lambda x: x, lambda x: x))
FuncScale(axis, functions=(lambda x: x, lambda x: x))
LogitScale(axis)
LogitScale(axis, 'clip')
LogitScale(axis, nonpositive='clip')
LogitScale(axis, use_overline=True)
AsinhScale(axis)
AsinhScale(axis, linear_width=2)
AsinhScale(axis, base=3)
AsinhScale(axis, subs=[2, 6])
# Old signature with axis as keyword.
FuncScale(axis=axis, functions=(lambda x: x, lambda x: x))
LogitScale(axis=axis)
LogitScale(axis=axis, nonpositive='clip')
LogitScale(axis=axis, use_overline=True)
AsinhScale(axis=axis)
AsinhScale(axis=axis, linear_width=2)
AsinhScale(axis=axis, base=3)
AsinhScale(axis=axis, subs=[2, 6])

Comment thread lib/matplotlib/scale.py Outdated
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
called with or without the *axis* parameter.

Copy link
Copy Markdown
Member

@timhoffm timhoffm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, on a technical level, I can already approve. It's only some docs left.

Instead of checking the types ourselves, try to bind the old signature,
and if possible, use it. Otherwise, try to use the new signature. This
is similar to `_api.select_matching_signature` without needing to write
a callable for each signature.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Release critical For bugs that make the library unusable (segfaults, incorrect plots, etc) and major regressions. topic: transforms and scales

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Should _make_axis_parameter_optional handle None?

2 participants