Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Simplify get_current_fig_manager(). #14085

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 1 commit into from
May 1, 2019

Conversation

anntzer
Copy link
Contributor

@anntzer anntzer commented Apr 29, 2019

It's longer to type(!) than its actual implementation
(gcf().canvas.manager), and mixes the pyplot and the OO-interfaces.

Also make plt.subplot_tool work even for non-pyplot-managed figures
-- there's no reason not to, it's just that such figures cannot be made
the "current" pyplot figure.

PR Summary

PR Checklist

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

@anntzer anntzer added this to the v3.2.0 milestone Apr 29, 2019
timhoffm
timhoffm previously approved these changes Apr 29, 2019
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.

get_current_figure_manager() is definitively nothing that should be in the user-facing pyplot API.

Not sure is should stay as a private function or maybe as a method of Figure. The deep nesting gcf().canvas.manager feels like there's a proper interface layer missing, but I'm not enough into the manager business to judge that.

@anntzer
Copy link
Contributor Author

anntzer commented Apr 29, 2019

I think the number of cases where a end user needs to access a manager is rare enough that being one additional layer deep is not something to worry about (basically, it's (mostly) only relevant when they're using pyplot to create the figures, but then still want to do stuff with the underlying toolkit widget...).

@timhoffm
Copy link
Member

I was more thinking along the lines: If people use the high-level pyplot API, the shouldn't have to do anything with managers. That mentioned additional layer would more be for experts and for having an internal clean structure.

@tacaswell
Copy link
Member

Accessing the manager can be very useful for setting custom window titles after the fact (which in turn controls how they show up in the task bar).

@anntzer
Copy link
Contributor Author

anntzer commented Apr 29, 2019

Fair enough, however the point that gcf().canvas.manager is shorter to type and avoids adding API layers for the sake of it remains :)

@timhoffm
Copy link
Member

I have still no clear view what a figure manager does and how the relations between Figure, Canvas and FigureManager are. Is this stuff documented somewhere? From what I found in the code, there's one of each for a figure.

  • Figure and Canvas reference each other mutually,
  • Likewise Canvas and FigureManager reference each other mutually,
  • FigureManager and Figure do not reference each other, but FigureManager.num == Figure.number.

Attempt do define what the classes are for:
Figure is the logic representation of the figure.
Canvas is the technical drawing area and defines the interface between the Figure and the actual backends.
FigureManager - well I have no clear idea. The docstring just says "Helper class for pyplot mode, wraps everything up into a neat bundle", which is not very informative. It seems to be a logic interface to the window used to display a figure on the screen. Would this class be better described as FigureWindow?

Depending on what the manager is actually meant for, it makes sense or not to keep it accessible directly through pyplot. I could also imagine that it makes sense to access the manager through the Figure.

@timhoffm timhoffm dismissed their stale review April 30, 2019 10:45

Withdrawing my approval for now as I've realized I don't really understand this stuff.

@anntzer
Copy link
Contributor Author

anntzer commented Apr 30, 2019

Very briefly, the FigureManager is what holds onto the native qt/gtk/wx/tk window that pyplot sets up to hold the canvas.

@ImportanceOfBeingErnest ImportanceOfBeingErnest changed the title Deprecate get_current_figure_manager(). Deprecate get_current_fig_manager(). Apr 30, 2019
@ImportanceOfBeingErnest
Copy link
Member

According to stackoverflow Q&As the main/most popular use case of plt.get_current_fig_manager() is to set the figure window's position or -size, or raise it to the top like

matplotlib.use(<backend>) 
...
plt.get_current_fig_manager().<backend-dependent way of setting window property>

Answers of this type have an accumulated number of some >50 votes. This seems like a clear sign that there is a lot of code in the wild that would suffer from the deprecation.

In that sense, what is the benefit of removing it?

@anntzer
Copy link
Contributor Author

anntzer commented Apr 30, 2019

If you're already doing something backend dependent, you should just do fig.canvas.<whatever> (canvas is a native widget; you can access the parent window with e.g. canvas.parent() or whatnot (depending on the backend)).
The advantage is that that'll work even if you later move away from pyplot... in my view, the manager is a pretty artificial intermediate layer here.

@tacaswell
Copy link
Member

I am 👍 on the internal changes, 👎 on deprecating it (there is no maintenance burden on it and as @ImportanceOfBeingErnest there would be a real user-cost to this change), 👍 for changing the docstring to saying "use this other thing instead".

@timhoffm In most (all?) cases the Canvas sub-class in the backend is multiply inherited from the base 'Widget' class of the GUI toolkit and just provides a way to paint the rendered figure to the screen. The manager classes take care of embedding that widget into a window, adding the toolbar, and any GUI specific set up details.

The work in #8777 / #4143 was on attempt at sorting this out.

@timhoffm
Copy link
Member

In the context of what I've understood so far, I'm in favor of leaving get_current_fig_manager() for now.

Even though the name is not great, this is the way to access the backend-specific window etc. In contrast, I see gcf().canvas.manager as an implementation detail. In general, why should a canvas know about it's containing window? If anything, I would expect something like gcf().get_manager() since the Figure is the logic representation. From there, you can either get to the drawing surface canvas or to the containing window. Since pyplot is a flat API, it's ok to have a top-level function for this.

@anntzer anntzer force-pushed the get_current_figure_manager branch from 86fe348 to d496e77 Compare April 30, 2019 22:34
Also make ``plt.subplot_tool`` work even for non-pyplot-managed figures
-- there's no reason not to, it's just that such figures cannot be made
the "current" pyplot figure.
@anntzer anntzer force-pushed the get_current_figure_manager branch from d496e77 to e615fe5 Compare April 30, 2019 22:35
@anntzer
Copy link
Contributor Author

anntzer commented Apr 30, 2019

To move this forward, I reverted the deprecation and just put in the simpler implementation and docstring.

@timhoffm timhoffm merged commit a84b905 into matplotlib:master May 1, 2019
@timhoffm timhoffm changed the title Deprecate get_current_fig_manager(). Simplify get_current_fig_manager(). May 1, 2019
@anntzer anntzer deleted the get_current_figure_manager branch May 1, 2019 09:41
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 this pull request may close these issues.

4 participants