Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Allow bool-like values for sharex/sharey #24362

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Dec 16, 2022
Merged

Conversation

vdbma
Copy link
Contributor

@vdbma vdbma commented Nov 4, 2022

PR Summary

This PR allows to use either 0 or 1 in place of False or True in sharex and sharey options. Fixes #24349.

PR Checklist

Tests and Styling

  • Has pytest style unit tests (and pytest passes). (everything passes except test_font_manager.py::test_get_font_names, and it would seem that it is because I have custom fonts installed)
  • Is Flake 8 compliant (install flake8-docstrings and run flake8 --docstring-convention=all).

Documentation

  • Documentation is sphinx and numpydoc compliant (the docs should build without error).
  • New plotting related features are documented with examples.

Release Notes

  • New features are marked with a .. versionadded:: directive in the docstring and documented in doc/users/next_whats_new/
  • API changes are marked with a .. versionchanged:: directive in the docstring and documented in doc/api/next_api_changes/
  • Release notes conform with instructions in next_whats_new/README.rst or next_api_changes/README.rst

@vdbma
Copy link
Contributor Author

vdbma commented Nov 4, 2022

I am not super happy with the implementation :

 _api.check_in_list(["all", "row", "col", "none", 0, 1, False, True]

The error message is clearer but with the if conditions above, False, True, 0 and 1 are not actually values that can be passed to sharex and sharey. In this case their value is changed to 'all' or 'none'.

Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

Thank you for opening your first PR into Matplotlib!

If you have not heard from us in a while, please feel free to ping @matplotlib/developers or anyone who has commented on the PR. Most of our reviewers are volunteers and sometimes things fall through the cracks.

You can also join us on gitter for real-time discussion.

For details on testing, writing docs, and our review process, please see the developer guide

We strive to be a welcoming and open project. Please follow our Code of Conduct.

lib/matplotlib/gridspec.py Outdated Show resolved Hide resolved
lib/matplotlib/gridspec.py Outdated Show resolved Hide resolved
lib/matplotlib/gridspec.py Outdated Show resolved Hide resolved
lib/matplotlib/gridspec.py Outdated Show resolved Hide resolved
@tacaswell tacaswell added this to the v3.7.0 milestone Nov 4, 2022
Copy link
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.

If I have understood the dev cal discussion from yesterday correctly, the way forward here is not special-handling 0 and 1 but

  • remove the isinstance(sharex, Integral) check. That warning is not needed anymore because sharex is keyword-only now.
  • rewrite the code to special-handle str, and bool-ducktype any other value, i.e.
    if isinstance(sharex, str):
        ...
    else:
        sharex = "all" if sharex else "none"
    

@jklymak
Copy link
Member

jklymak commented Nov 7, 2022

@vdbma, is the comment about the code re-organization from @timhoffm above clear?

@vdbma
Copy link
Contributor Author

vdbma commented Nov 7, 2022

Yes very clear, thanks for the feedback ! I will implement it when I have some time.

@vdbma
Copy link
Contributor Author

vdbma commented Nov 8, 2022

I implemented what you suggested, but there are still two points that bother me and to which I did not find an elegant solution (yet):

  • As was discussed above _api.check_in_list is what formats the error message. However the values that sharex takes when this function is called already has been normalised to one of "all", "row", "col", "none". Thus it will never occur that sharex still has one of the values 0, 1, False, True , yet we still check that it might. But we can't remove the "useless" values, because then the error message would not be clear regarding what values are allowed for the user to use. This feels somewhat inconsistent to me.
  • With the current implementation (suggested by @timhoffm) passing any other integer/float value than 0 or 1 is not a problem. Do we actually want this behaviour ? (if so the test added in test_subplots.py::test_shared should be removed)

lib/matplotlib/gridspec.py Outdated Show resolved Hide resolved
lib/matplotlib/gridspec.py Outdated Show resolved Hide resolved
lib/matplotlib/gridspec.py Outdated Show resolved Hide resolved
@timhoffm
Copy link
Member

  • As was discussed above _api.check_in_list is what formats the error message. However the values that sharex takes when this function is called already has been normalised to one of "all", "row", "col", "none". Thus it will never occur that sharex still has one of the values 0, 1, False, True , yet we still check that it might. But we can't remove the "useless" values, because then the error message would not be clear regarding what values are allowed for the user to use. This feels somewhat inconsistent to me.

The fundamental issue here is that the logic needs special handling of some of the existing values. Thus, the _check_in_list() site does not see the full range of possible values. As long as we build the message from the check list, we either lack allowed values in the message or we have to extend the list beyond what can actually be used in the current context.

I'm mostly ok to have the extra values in here. - The alternative would be to expand the semantics of the _print_supported_values parameter so that we can do:

check_in_list(
    ["all", "row", "col", "none"],
    _print_supported_values=["all", "row", "col", "none", True, False],
    sharex=sharex, sharey=sharey)
  • With the current implementation (suggested by @timhoffm) passing any other integer/float value than 0 or 1 is not a problem. Do we actually want this behaviour ? (if so the test added in test_subplots.py::test_shared should be removed)

Yes. To be clear: Conceptually, we don't accept special values 0, 1 as synonyms to True and False. We only support the concept of duck-typing, which says that you can pass any truthy or falsy values. This is also what happens in most cases automatically when you have conditions like if sharex:.

N.b.: For that reason, the check in list message should not list 0, 1 explicitly.

@vdbma
Copy link
Contributor Author

vdbma commented Nov 20, 2022

Thanks you for the feedback ! I better understand the logic.

lib/matplotlib/tests/test_subplots.py Outdated Show resolved Hide resolved
Copy link
Member

@tacaswell tacaswell left a comment

Choose a reason for hiding this comment

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

Please do not remove the test.

Anyone can dismiss this review.

@tacaswell
Copy link
Member

@vdbma are you still interested in working on this PR?

I'm going to push this to 3.8, but if it is done there is no reason it can not be merged for 3.7.

@tacaswell tacaswell modified the milestones: v3.7.0, v3.8.0 Dec 15, 2022
@vdbma
Copy link
Contributor Author

vdbma commented Dec 15, 2022

Yes, very much so ! Sorry for the late contribution.

@vdbma
Copy link
Contributor Author

vdbma commented Dec 15, 2022

As of now the documentation for sharex says:

...
sharex, sharey : bool or {'none', 'all', 'row', 'col'}, default: False
Controls sharing of properties among x (sharex) or y (sharey) axes:
True or 'all': x- or y-axis will be shared among all subplots.
False or 'none': each subplot x- or y-axis will be independent.
...

Should I change it so that it is explicit that non-str values will be cast to boolean or should it remain an implicit behaviour ?

@timhoffm
Copy link
Member

timhoffm commented Dec 15, 2022

Please leave it as is. The primary logic type here is bool. That many things can be interpreted as bool is a language property of Python, which is often used. It would be rather distracting to mention this in every context that supports it.

@tacaswell
Copy link
Member

Yes, very much so ! Sorry for the late contribution.

Great and no worries!

@tacaswell tacaswell dismissed their stale review December 15, 2022 23:42

test re-added.

@QuLogic QuLogic changed the title Using 0 or 1 as bool in sharex/sharey Allow bool-like values for sharex/sharey Dec 15, 2022
@QuLogic
Copy link
Member

QuLogic commented Dec 15, 2022

This could do with a squash, by you if you're comfortable with it, or at merge time.

@timhoffm timhoffm merged commit 2828912 into matplotlib:main Dec 16, 2022
@timhoffm
Copy link
Member

I've squashed during merge.

@vdbma thanks, and congratulations on your first contribution to Matplotlib! We hope to see you again.

@timhoffm timhoffm modified the milestones: v3.8.0, v3.7.0 Dec 16, 2022
raphaelquast pushed a commit to raphaelquast/matplotlib that referenced this pull request Mar 16, 2023

Co-authored-by: Marc Van den Bossche <marc.vanden-bossche@univ-grenoble-alpes.fr>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Bug]: sharex and sharey don't accept 0 and 1 as bool values
6 participants
Morty Proxy This is a proxified and sanitized view of the page, visit original site.