Skip to content

[Bug]: AxesSubplot.get_yticks not returning the actual printed ticks #23717

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

Closed
suuuehgi opened this issue Aug 23, 2022 · 3 comments · Fixed by #23746
Closed

[Bug]: AxesSubplot.get_yticks not returning the actual printed ticks #23717

suuuehgi opened this issue Aug 23, 2022 · 3 comments · Fixed by #23746
Milestone

Comments

@suuuehgi
Copy link

suuuehgi commented Aug 23, 2022

Bug summary

get_x/yticks seems to have some padding but does not return the actual printed ticks.

Code for reproduction

fig, ax = plt.subplots()
ax.loglog( range(100), range(100) )
print( ax.get_yticks() )
array([1.e-02, 1.e-01, 1.e+00, 1.e+01, 1.e+02, 1.e+03, 1.e+04])

so1

Actual outcome

fig, ax = plt.subplots()
ax.loglog( range(100), range(100) )

ax2 = ax.twinx()
ax2.set_yscale('log')
ax2.set_ylim( ax.get_ylim() )

yields a correct visual equivalence

so2

but adding ax2.set_yticks( ax.get_yticks() )

fig, ax = plt.subplots()
ax.loglog( range(100), range(100) )

ax2 = ax.twinx()
ax2.set_yscale('log')
ax2.set_ylim( ax.get_ylim() )

ax2.set_yticks( ax.get_yticks() ) # <---

yields:
so3

Expected outcome

Both axes with equal visual appearance when using ax2.set_yticks( ax.get_yticks() ).

Additional information

Why is this behavior problematic?

Consider e.g.:

ax2.set_yticks( ticks=ax.get_yticks(), 
                labels=[ "{:.2f}".format( my_transform(i) ) for i in ax.get_yticks() ] )

Thanks for any help / investigation!

Operating system

Arch

Matplotlib Version

3.5.2

Matplotlib Backend

module://matplotlib_inline.backend_inline

Python version

3.10.5

Jupyter version

jupyter lab --version == 3.4.4

Installation

Linux package manager

@tacaswell
Copy link
Member

If you swap the order of setting the limits and setting the ticks it works as expected.

get_yticks may return more ticks than are shown (for some historical reasons, some performance, and some good reasons). When you pass the tick locations to the second axis it looks at the inconsistency from "please use these limits" and "please show THESE ticks" (which is a FixedLocator rather than a LogLocator) it adjust the limits (rather than clipping the ticks).

I do not think there is much we can do here without breaking other behavior. Maybe get_yticks could get a "clip to current limits" opt-in flag, but I am not sure that is worth it as the fix here is "do not do extra work".

@suuuehgi
Copy link
Author

suuuehgi commented Aug 26, 2022

Thank you very much for the answer!

All right ... It makes total sense to adjust the limits when passing ticks of a broader range.

So, I just remember: get_[x/y]ticks returns for whatever reason more ticks than printed, hence

  1. first set the ticks
  2. than the limits to cut the ticks.

P.S. Side question: Is there any guide, tutorial or a like about the inner workings of mpl apart from the doc-strings?

@tacaswell
Copy link
Member

I'm working on a PR to add a note about returning locations out of the current view limits.

As for where to get more information:

  • https://matplotlib.org/3.6.0/users/explain/index.html has explanation of some parts of the code (we are (slowly) working on re-organizing the docs and will be moving more here)
  • http://www.aosabook.org/en/matplotlib.html is old, but still mostly correct about the overall architecture
  • read the source! While there are some complex parts of code, a majority of the code base is relatively readable.
  • ask questions on discourse or gitter. Not everything about the project is documented (or documented in a way or place that is easy to find or understand) and at least I really enjoy talking about Matplotlib :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants