Movatterモバイル変換


[0]ホーム

URL:


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

Sign up
Appearance settings

Adding subplotpars to the plot stack#11796

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Draft
fredrik-1 wants to merge2 commits intomatplotlib:main
base:main
Choose a base branch
Loading
fromfredrik-1:interactive_stack_bug

Conversation

fredrik-1
Copy link
Contributor

The following code show that it is a problem with the interactive navigation whentight_layout is True. The problem is thattight_layout use the figures subplot parameters when calculating the new parameters (I am not really sure why, to use theaxes positions also seems to work in the tests I have done) and those are not stored in the plot stack and thus not updated when the back, forward and home buttons are used.

   import matplotlib.pyplot as plt   import numpy as np   plt.close('all')   fig, ax=plt.subplots(1,1, num=1, clear=True)   fig.set_tight_layout(True)   ax.plot(np.random.randn(1000))   fig.canvas.toolbar.push_current()   plt.pause(1)   for i in range(1,10):       ax.set_xlim((100*i, 1000))       ax.set_ylim((-10+i,10-i))       fig.canvas.toolbar.push_current()       plt.pause(0.5)   for i in range(12):       fig.canvas.toolbar.back()       plt.pause(0.5)

My solution that seems to work is to add the subplot parameters to the stack. I add the same parameters for all axis even though you don't have to but the code became clean and not much is changed in this pr.

I also added aget function for the subplot parameters because I want one.

One issue might be that some figure don't have a subplot parameters but I don't think that it is possible.

I guess that it should be good with some tests for this interactive behavior and I am going to look into that.

  • Has Pytest style unit tests
  • Code is PEP 8 compliant
  • New features are documented, with examples if plot related
  • Documentation is sphinx and numpydoc compliant
  • Added an entry to doc/users/next_whats_new/ if major new feature (follow instructions in README.rst there)
  • Documented in doc/api/api_changes.rst if API changed in a backward-incompatible way

@jklymak
Copy link
Member

This is probably fine, but have you tried constrained layout? It also seems to me that this info is best kept on the GridSpec. I am away from computer a few days so can’t dig into it but each subplotspec should have a parent GridSpec that I thought held all this.

@fredrik-1
Copy link
ContributorAuthor

Yes, the subplot parameters are also included in the gridspec for a subplot axes but thetight_layout that are used here lives in the figure (the gridspec just reads the data fromFigure.subplotpars) so I think thatFigure.subplotpars should be used.

I have tested this implementation for different kinds ofaxes and it seems to work as expected.

jklymak reacted with thumbs up emoji

@fredrik-1
Copy link
ContributorAuthor

Added an "interactive" test that fails on master. Any comments about the test structure? I am going to write more similar tests.

Are there any reason to test more than one backend?

ax._set_view(view)
# Restore both the original and modified positions
ax._set_position(pos_orig, 'original')
ax._set_position(pos_active, 'active')

self.canvas.figure.subplotpars.update(**subplotpars)
Copy link
Member

Choose a reason for hiding this comment

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

I'm a little confused why you don't just do all this with thesubplotpars object directly, rather than making a dictionary and then passing one back in. Does that not work for some reason?

Copy link
ContributorAuthor

Choose a reason for hiding this comment

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

I am not sure if I thought about it but I have tested it now and it didn't work well in same cases for same reason.

I also think that it feels better to read and copy the parameters and update the same object than copy the whole object and change object in_update_view. I am not sure now but it is possibly that gridspec has a view to the SubplotParams object in figure.

Copy link
Member

Choose a reason for hiding this comment

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

This does seem very odd...

Copy link
Contributor

Choose a reason for hiding this comment

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

This is very likely because subplotpars are mutable, so even if you push them onto the stack they'll get mutated after the fact unless you make a copy first.

@fredrik-1fredrik-1force-pushed theinteractive_stack_bug branch 9 times, most recently from931d430 to6137e15CompareAugust 6, 2018 08:07
@fredrik-1
Copy link
ContributorAuthor

I added some tests, maybe to many, maybe to slow. The tests work on my computer and travis with python 3.6.

I don't understand what I can to make them pass on python 3.5 though. I get the following error

==================================== ERRORS ====================================_____________________________ ERROR collecting gw1 _____________________________Different tests were collected between gw0 and gw1. The difference is:--- gw0+++ gw1@@ -649,16 +649,16 @@ lib/matplotlib/tests/test_axes.py::test_tick_padding_tightbbox lib/matplotlib/tests/test_axes.py::test_zoom_inset lib/matplotlib/tests/test_axes.py::test_spines_properbbox_after_zoom-lib/matplotlib/tests/test_backend_bases.py::test_home_button2[png]-lib/matplotlib/tests/test_backend_bases.py::test_back_button7[png]-lib/matplotlib/tests/test_backend_bases.py::test_back_button4[png] lib/matplotlib/tests/test_backend_bases.py::test_back_button2[png] lib/matplotlib/tests/test_backend_bases.py::test_back_button3[png] lib/matplotlib/tests/test_backend_bases.py::test_home_button1[png] lib/matplotlib/tests/test_backend_bases.py::test_back_button5[png]+lib/matplotlib/tests/test_backend_bases.py::test_home_button3[png]+lib/matplotlib/tests/test_backend_bases.py::test_back_button7[png]+lib/matplotlib/tests/test_backend_bases.py::test_home_button2[png]+lib/matplotlib/tests/test_backend_bases.py::test_back_button4[png]+lib/matplotlib/tests/test_backend_bases.py::test_back_button1[png] lib/matplotlib/tests/test_backend_bases.py::test_back_button6[png]-lib/matplotlib/tests/test_backend_bases.py::test_home_button3[png]-lib/matplotlib/tests/test_backend_bases.py::test_back_button1[png] lib/matplotlib/tests/test_backend_bases.py::test_uses_per_path lib/matplotlib/tests/test_backend_bases.py::test_get_default_filename lib/matplotlib/tests/test_backend_bases.py::test_non_gui_warning=========================== short test summary info ============================ERROR gw1

The problem is due to multiprocessing (or multi threading) together with parametrized tests but I don't understand how the information I have found about the error is related to my own code.

@QuLogic
Copy link
Member

You don't need all of thosetest_home_button* functions; you can usepytest.mark.parametrize on the single class for it.

@tacaswelltacaswell added this to thev3.1 milestoneAug 7, 2018
@tacaswell
Copy link
Member

That is weird that it is collecting in a different order. It is likely due to the random iteration order of dictionaries in py3.5, presumably someplace inside of pytest.

Would this be fixed by (modestly) bumping the pytest version? IIRC 3.5 is currently pinned to the minimum versions of many of our dependencies.

I wonder if moving to a paramaterized class (or one paramaterized function) as@QuLogic suggested would solve this problem?

@WeatherGod
Copy link
Member

WeatherGod commentedAug 8, 2018 via email

Just pointing out that not all figures have subplot axes. Some figures willhave axes placed manually. I haven't read enough of this PR to know if thatis an issue or not.
On Tue, Aug 7, 2018 at 8:03 PM, Thomas A Caswell ***@***.***> wrote: That is weird that it is collecting in a different order. It is likely due to the random iteration order of dictionaries in py3.5, presumably someplace inside of pytest. Would this be fixed by (modestly) bumping the pytest version? IIRC 3.5 is currently pinned to the minimum versions of many of our dependencies. I wonder if moving to a paramaterized class (or one paramaterized function) as@QuLogic <https://github.com/QuLogic> suggested would solve this problem? — You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub <#11796 (comment)>, or mute the thread <https://github.com/notifications/unsubscribe-auth/AARy-L4_oodm0hheQLVYV2uSCc0e7CZRks5uOirugaJpZM4Vlfyf> .

@QuLogic
Copy link
Member

Well, it's definitely a thing caused by pytest-xdist, possibly related topytest-dev/pytest#920 which should be fixed with 3.2.0.

@fredrik-1
Copy link
ContributorAuthor

You don't need all of those test_home_button* functions; you can use pytest.mark.parametrize on the single class for it.

I have tried that in a couple of ways but it doesn't seem to work together with thecheck_figures_equal decorator. The input to that decorator should be a function with two arguments. I don't understand the behavior though. pytests seems to do something strange and don't work as I would expect.

@tacaswelltacaswell modified the milestones:v3.1.0,v3.2.0Feb 26, 2019
@tacaswelltacaswell removed this from thev3.2.0 milestoneSep 5, 2019
@tacaswelltacaswell added this to thev3.3.0 milestoneSep 5, 2019
@QuLogicQuLogic modified the milestones:v3.3.0,v3.4.0May 2, 2020
@jklymakjklymak marked this pull request as draftSeptember 10, 2020 15:13
@QuLogicQuLogic modified the milestones:v3.4.0,unassignedJan 21, 2021
@anntzer
Copy link
Contributor

anntzer commentedMay 6, 2021
edited
Loading

Looking at the big picture, the request seems reasonable (I still need to look at the implementation carefully), but probably we need to stop pushing subplotparams on the stack when using the interactive subplottool, otherwise an enormous number of entries will be generated while moving the sliders. [Edit: actually that's not a problem, it's up to subplottool to push an entry on the stack in if it wants]
I'll have a look...


Edit: The original repro script given at the top indeed shows the problem with the various builtin interactive backends, but not with mplcairo. I'll want to investigate that first, as that may just be an issue elsewhere that we'd be papering over...

@anntzeranntzer self-assigned thisMay 6, 2021
@story645story645 modified the milestones:unassigned,needs sortingOct 6, 2022
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Reviewers

@tacaswelltacaswelltacaswell left review comments

@anntzeranntzeranntzer left review comments

@jklymakjklymakjklymak left review comments

At least 1 approving review is required to merge this pull request.

Assignees

@anntzeranntzer

Projects
None yet
Milestone
future releases
Development

Successfully merging this pull request may close these issues.

7 participants
@fredrik-1@jklymak@QuLogic@tacaswell@WeatherGod@anntzer@story645

[8]ページ先頭

©2009-2025 Movatter.jp