Skip to content
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

Allow passing a transformation to secondary_xaxis/_yaxis #25224

Merged
merged 1 commit into from
Mar 8, 2024

Conversation

ZachDaChampion
Copy link
Contributor

@ZachDaChampion ZachDaChampion commented Feb 15, 2023

PR Summary

resolves #25119.

I'm new to Matplotlib development so not sure if this is the best way to do this. I added a transform parameter to secondary_xaxis and secondary_yaxis and passed that through into SecondaryAxis._set_location(), where the transform is blended.

if self._orientation == 'x':
    # An x-secondary axes is like an inset axes from x = 0 to x = 1 and
    # from y = pos to y = pos + eps, in the parent's transAxes coords.
    bounds = [0, self._pos, 1., 1e-10]

    # If a transformation is provided, use its y component rather than
    # the parent's transAxes. This can be used to place axes in the data
    # coords, for instance.
    if transform is not None:
        transform = transforms.blended_transform_factory(
            self._parent.transAxes, transform)
else:  # 'y'
    bounds = [self._pos, 0, 1e-10, 1]
    if transform is not None:
        transform = transforms.blended_transform_factory(
            transform, self._parent.transAxes)  # Use provided x axis

# If no transform is provided, use the parent's transAxes
if transform is None:
    transform = self._parent.transAxes

I also updated test_secondary_xy() and test_secondary_fail() to test the transform.

I'm not entirely sure if/where I'm meant to put .. versionchanged:: in the docsting, but I'm happy to add it if it's needed.

PR Checklist

Documentation and Tests

  • Has pytest style unit tests (and pytest passes)
  • 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

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.

@jklymak
Copy link
Member

jklymak commented Feb 15, 2023

This looks really useful, and a quick glance the code is great. Can we add an example, at least in the issue that shows the usefulness of this? Probably want one in the example gallery as well. I had to read your code to understand the context here, which if I understand is to allow the secondary xaxis to have a y position specified in data co-ordinates rather than just axes co-ordinates.

If that is the case, what happens if the y data limits are set so the secondary axis is out of the Axes viewport?

@jklymak jklymak changed the title Allow passing a transformation to a secondary plot Allow passing a transformation to secondary_xaxis/_yaxis Feb 15, 2023
@ZachDaChampion
Copy link
Contributor Author

@jklymak Yes, you are correct on the context. Right now, if an axis is out of the viewport it isn't drawn. The existing function behaves the same if you give it a location outside of the viewport. E.g. x2 = ax.secondary_xaxis(1.5) is not drawn. If we want it to do something else I'd be happy to change it.

Good point on the examples, I'll take care of that.

@melissawm
Copy link
Contributor

Hi @ZachDaChampion - it seems you also need a rebase here to incorporate changes made in the main branch. Here's a handy guide: https://matplotlib.org/stable/devel/development_workflow.html#rebasing-on-upstream-main

Feel free to ping if you need more guidance!

@ksunden
Copy link
Member

ksunden commented Apr 4, 2023

It appears that you did a merge instead of a rebase, which results in 884 commits (!!) showing up here.

We have some docs for recovering from situations like this:

https://matplotlib.org/stable/devel/development_workflow.html#recovering-from-mess-ups

@ZachDaChampion
Copy link
Contributor Author

It appears that you did a merge instead of a rebase, which results in 884 commits (!!) showing up here.

We have some docs for recovering from situations like this:

https://matplotlib.org/stable/devel/development_workflow.html#recovering-from-mess-ups

My bad, I didn't realize I pushed that version. Thanks for the link

lib/matplotlib/axes/_axes.py Show resolved Hide resolved
lib/matplotlib/axes/_axes.py Outdated Show resolved Hide resolved
lib/matplotlib/axes/_axes.py Outdated Show resolved Hide resolved
lib/matplotlib/axes/_axes.py Outdated Show resolved Hide resolved
lib/matplotlib/axes/_axes.py Outdated Show resolved Hide resolved
lib/matplotlib/axes/_secondary_axes.py Outdated Show resolved Hide resolved
lib/matplotlib/axes/_secondary_axes.py Outdated Show resolved Hide resolved
lib/matplotlib/axes/_secondary_axes.py Outdated Show resolved Hide resolved
lib/matplotlib/axes/_secondary_axes.py Outdated Show resolved Hide resolved
lib/matplotlib/tests/test_axes.py Outdated Show resolved Hide resolved
@QuLogic
Copy link
Member

QuLogic commented Apr 15, 2023

Now that we have typing stubs, it looks like you'll have to update the corresponding lines in the .pyi files. Also, please rebase to fix the CircleCI failures.

@melissawm
Copy link
Contributor

Gentle ping to the reviewers - can you take another look here? Thanks!

Copy link
Member

@QuLogic QuLogic left a comment

Choose a reason for hiding this comment

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

Just a couple minor fixes.

lib/matplotlib/axes/_axes.py Outdated Show resolved Hide resolved
lib/matplotlib/axes/_secondary_axes.py Outdated Show resolved Hide resolved
lib/matplotlib/axes/_secondary_axes.py Outdated Show resolved Hide resolved
@ZachDaChampion
Copy link
Contributor Author

I can rebase later if needed

Copy link
Member

@QuLogic QuLogic left a comment

Choose a reason for hiding this comment

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

Sorry we took a while to get back to this again. Just a couple minor fixes, but otherwise LGTM.


fig, ax = plt.subplots(layout='constrained')
x = np.arange(0, 10)
np.random.seed(34)
Copy link
Member

Choose a reason for hiding this comment

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

We almost always use 19680801 as seed

Suggested change
np.random.seed(34)
np.random.seed(19680801)

else:
raise ValueError('secondary_yaxis location must be either '
if not (location in ['left', 'right'] or isinstance(location, Real)):
raise ValueError('secondary_xaxis location must be either '
Copy link
Member

Choose a reason for hiding this comment

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

Typo:

Suggested change
raise ValueError('secondary_xaxis location must be either '
raise ValueError('secondary_yaxis location must be either '

Comment on lines 99 to 100
# Make sure transform is a Transform or None.
_api.check_isinstance((transforms.Transform, None), transform=transform)
Copy link
Member

Choose a reason for hiding this comment

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

I wouldn't bother with the comment; the function call is clear:

Suggested change
# Make sure transform is a Transform or None.
_api.check_isinstance((transforms.Transform, None), transform=transform)
_api.check_isinstance((transforms.Transform, None), transform=transform)

Add transform argument to secondary axes

Update _secax_docstring

Move new params to end of functions

Add input check to secondary axes

Add tests

Add examples

Move transform type checks and improve docs

Add type stubs

Update _secax_docstring

Move new params to end of functions

Add input check to secondary axes

Move transform type checks and improve docs

Fix rebase error

Fix stub for SecondaryAxis.__init__

Clarify example

Add default param to secax constructor

Fix stub for secax constructor

Simplify imports

Co-authored-by: Elliott Sales de Andrade <quantum.analyst@gmail.com>

Remove redundancy in docs

Co-authored-by: Elliott Sales de Andrade <quantum.analyst@gmail.com>

Fix typo
@QuLogic
Copy link
Member

QuLogic commented Feb 23, 2024

I've rebased, squashed into one commit, fixed the typos, and force pushed here in the interest of getting this merged.

@timhoffm timhoffm merged commit 5abcae2 into matplotlib:main Mar 8, 2024
42 of 45 checks passed
@timhoffm
Copy link
Member

timhoffm commented Mar 8, 2024

Thanks @ZachDaChampion and congratulations on your first contribution to Matplotlib. 🎉 We'd love to see you back!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Documentation: examples files in galleries/examples topic: axes
Projects
Development

Successfully merging this pull request may close these issues.

[ENH]: secondary_x/yaxis accept transform argument
6 participants