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

Attach a FigureCanvasBase by default to Figures.#12450

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

Merged
tacaswell merged 1 commit intomatplotlib:masterfromanntzer:defaultcanvas
Nov 11, 2018

Conversation

anntzer
Copy link
Contributor

This is particularly useful for headless cases, where one just wants to
take advantage ofprint_figure, which is defined on the base class.
For example, one can now do

for <loop>:    figure = Figure()    # do some plotting    figure.savefig(...)

and letfigure get gc'd at the next loop iteration; a pyplot-based
solution would instead have to explicitly close() the figure or reuse it
after clf()'ing it.

Also simplifies various places in the codebase where we had to handle
the case of.canvas = None previously.

xref#11657,#12447.

PR Summary

PR Checklist

  • Has Pytest style unit tests
  • Code isFlake 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

@anntzeranntzer added this to thev3.1 milestoneOct 8, 2018
@timhoffm
Copy link
Member

First thought: Does this involve any costly setup logic? We are already quite slow in creating figures.
Answer: Apparently not. -> Ok.

Second thought: IsFigureCanvasBase the right class? It's not used explicitly except in some tests. Should we maybe have

class PrintableFigureCanvas(FigureCanvasBase):    pass

just for semantic reasons?
Maybe not. Not sure myself.

Third thought: Do we now get more strange behavior or error message when we try things that would before fail due to the missing canvas?

@anntzer
Copy link
ContributorAuthor

  1. I strongly doubt it matters performance-wise (the base class__init__ just sets a bunch of attributes), and I guess you actually did time it :)
  2. Seems overkill to me.
  3. Figure().canvas.draw() now does nothing instead of raising an AttributeError ("None has no attribute "draw"), but that's sort of the point of the PR... (I guess youcould split out draw() in its own subclass of FigureCanvasBase but... let's not.)
    It shouldn't be too hard to revert this if we merge it early in the 3.1 cycle and it turns out to be problematic :)

@timhoffm
Copy link
Member

timhoffm commentedOct 8, 2018
edited
Loading

and I guess you actually did time it :)

No just looked at the code 😄

  1. Ok.

It shouldn't be too hard to revert this if we merge it early in the 3.1 cycle and it turns out to be problematic :)

Doesn't sound well thought through. I haven't either, but I'm hesitant to introduce a code change with an effect that we do not overlook.

@anntzer
Copy link
ContributorAuthor

Doesn't sound well thought through. I haven't either, but I'm hesitant to introduce a code change with an effect that we do not overlook.

I actually really think it's not going to cause any problems, but as usual things are tied up in so many knots in mpl that it's hard to know if we don't try.

"rotation disabled. Set canvas then call "
"Axes3D.mouse_init().")

self._cids = [
Copy link
Member

Choose a reason for hiding this comment

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

Concerned that if we are hitting this code path with the base canvas and then it gets replaced the subscriptions will not work.

On the other hand, you are no worse than you are now.

Copy link
ContributorAuthor

Choose a reason for hiding this comment

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

So I'll leave it as it is until someone complains :)

@tacaswell
Copy link
Member

This code was last touched inb0807ae which was primarily reverting#1125

The originalself.canvas = None and the logic of the canvas setting its self to the Figure came in in770d0a0

I suspect looking at why#1125 failed would be a good guide to if we are missing something here. From a very quick look, that PR defaulted to getting the current backend from pyplot (more-or-less) where as this is is going with the base class which has just enough logic to fall-back on save.

Another option is to makecanvas a property and defer creating a canvas until someone asks for it, but I am not sure it is worth the complexity / runtime cost.

This is particularly useful for headless cases, where one just wants totake advantage of `print_figure`, which is defined on the base class.For example, one can now do    for <loop>:        figure = Figure()        # do some plotting        figure.savefig(...)and let `figure` get gc'd at the next loop iteration; a pyplot-basedsolution would instead have to explicitly close() the figure or reuse itafter clf()'ing it.Also simplifies various places in the codebase where we had to handlethe case of `.canvas = None` previously.
@anntzer
Copy link
ContributorAuthor

Looking at#1457 (comment) it looks like#1125 failed because not all Canvas classes have the same constructor signature, but that's not a problem here.
I think#1457 (which was likewise rejected) failed because it also tried to construct a FigureManager by default (even if it doesn't use it, it's still present) to workaround that signature variation.

In both cases I think using FigureCanvasBase avoids these problems.

Copy link
Contributor

@dopplershiftdopplershift left a comment

Choose a reason for hiding this comment

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

This seems reasonable to me, if for no other reason than the number of checks forNone it removes.

@tacaswelltacaswell merged commit8fd45c0 intomatplotlib:masterNov 11, 2018
@anntzeranntzer deleted the defaultcanvas branchNovember 11, 2018 11:04
tacaswell added a commit to tacaswell/matplotlib that referenced this pull requestJan 12, 2020
In380c531 /matplotlib#12450 we set thedefault canvas on Figure `__init__` to FigureCanvasBase but were stillsetting it to `None` in `__setstate__`.
tacaswell added a commit to tacaswell/matplotlib that referenced this pull requestJan 13, 2020
In380c531 /matplotlib#12450 we set thedefault canvas on Figure `__init__` to FigureCanvasBase but were stillsetting it to `None` in `__setstate__`.
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Reviewers

@WeatherGodWeatherGodWeatherGod left review comments

@tacaswelltacaswelltacaswell approved these changes

@dopplershiftdopplershiftdopplershift approved these changes

Assignees
No one assigned
Labels
None yet
Projects
None yet
Milestone
v3.1.0
Development

Successfully merging this pull request may close these issues.

5 participants
@anntzer@timhoffm@tacaswell@dopplershift@WeatherGod

[8]ページ先頭

©2009-2025 Movatter.jp