-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Move show() to somewhere naturally inheritable / document what pyplot expects from a backend. #23101
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
Move show() to somewhere naturally inheritable / document what pyplot expects from a backend. #23101
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2840,6 +2840,53 @@ def create_with_canvas(cls, canvas_class, figure, num): | |
""" | ||
return cls(canvas_class(figure), num) | ||
|
||
@classmethod | ||
def start_main_loop(cls): | ||
""" | ||
Start the main event loop. | ||
|
||
This method is called by `.FigureManagerBase.pyplot_show`, which is the | ||
implementation of `.pyplot.show`. To customize the behavior of | ||
`.pyplot.show`, interactive backends should usually override | ||
`~.FigureManagerBase.start_main_loop`; if more customized logic is | ||
necessary, `~.FigureManagerBase.pyplot_show` can also be overridden. | ||
""" | ||
|
||
@classmethod | ||
def pyplot_show(cls, *, block=None): | ||
""" | ||
Show all figures. This method is the implementation of `.pyplot.show`. | ||
|
||
To customize the behavior of `.pyplot.show`, interactive backends | ||
should usually override `~.FigureManagerBase.start_main_loop`; if more | ||
customized logic is necessary, `~.FigureManagerBase.pyplot_show` can | ||
also be overridden. | ||
|
||
Parameters | ||
---------- | ||
block : bool, optional | ||
Whether to block by calling ``start_main_loop``. The default, | ||
None, means to block if we are neither in IPython's ``%pylab`` mode | ||
nor in ``interactive`` mode. | ||
""" | ||
managers = Gcf.get_all_fig_managers() | ||
if not managers: | ||
return | ||
for manager in managers: | ||
try: | ||
manager.show() # Emits a warning for non-interactive backend. | ||
except NonGuiException as exc: | ||
_api.warn_external(str(exc)) | ||
if block is None: | ||
# Hack: Are we in IPython's %pylab mode? In pylab mode, IPython | ||
# (>= 0.10) tacks a _needmain attribute onto pyplot.show (always | ||
# set to False). | ||
ipython_pylab = hasattr( | ||
getattr(sys.modules.get("pyplot"), "show", None), "_needmain") | ||
block = not ipython_pylab and not is_interactive() | ||
if block: | ||
cls.start_main_loop() | ||
|
||
def show(self): | ||
""" | ||
For GUI backends, show the figure window and redraw. | ||
|
@@ -3518,7 +3565,12 @@ def new_figure_manager_given_figure(cls, num, figure): | |
|
||
@classmethod | ||
def draw_if_interactive(cls): | ||
if cls.mainloop is not None and is_interactive(): | ||
manager_class = cls.FigureCanvas.manager_class | ||
# Interactive backends reimplement start_main_loop or pyplot_show. | ||
backend_is_interactive = ( | ||
manager_class.start_main_loop != FigureManagerBase.start_main_loop | ||
timhoffm marked this conversation as resolved.
Show resolved
Hide resolved
|
||
or manager_class.pyplot_show != FigureManagerBase.pyplot_show) | ||
if backend_is_interactive and is_interactive(): | ||
manager = Gcf.get_active() | ||
if manager: | ||
manager.canvas.draw_idle() | ||
|
@@ -3546,8 +3598,8 @@ def show(cls, *, block=None): | |
# Hack: Are we in IPython's %pylab mode? In pylab mode, IPython | ||
# (>= 0.10) tacks a _needmain attribute onto pyplot.show (always | ||
# set to False). | ||
from matplotlib import pyplot | ||
ipython_pylab = hasattr(pyplot.show, "_needmain") | ||
ipython_pylab = hasattr( | ||
getattr(sys.modules.get("pyplot"), "show", None), "_needmain") | ||
Comment on lines
3598
to
+3602
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Move this to a helper function in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The duplication is only temporary, because the version in _Backend.show will go away as I plan to get rid of the _Backend class, which was an implementation detail anyways. (I'm not doing it immediately because the ipympl backend has started relying on it, but I plan to help them to get rid of that use, either going back to the old-style fully manual API if they want a long backcompat, or going to the new class-based API.) |
||
block = not ipython_pylab and not is_interactive() | ||
if block: | ||
cls.mainloop() | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we also want to check if pypplot is already imported?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure.