diff --git a/lib/matplotlib/backend_bases.py b/lib/matplotlib/backend_bases.py index 98aca9251d4..bbc4e02b377 100644 --- a/lib/matplotlib/backend_bases.py +++ b/lib/matplotlib/backend_bases.py @@ -2426,55 +2426,27 @@ def new_timer(self, *args, **kwargs): return TimerBase(*args, **kwargs) def flush_events(self): - """ - Flush the GUI events for the figure. Implemented only for - backends with GUIs. - """ - raise NotImplementedError + """Flush the GUI events for the figure. - def start_event_loop(self, timeout): + Interactive backends need to reimplement this method. """ - Start an event loop. This is used to start a blocking event - loop so that interactive functions, such as ginput and - waitforbuttonpress, can wait for events. This should not be - confused with the main GUI event loop, which is always running - and has nothing to do with this. - This is implemented only for backends with GUIs. - """ - raise NotImplementedError + def start_event_loop(self, timeout=0): + """Start a blocking event loop. - def stop_event_loop(self): - """ - Stop an event loop. This is used to stop a blocking event - loop so that interactive functions, such as ginput and - waitforbuttonpress, can wait for events. + Such an event loop is used by interactive functions, such as `ginput` + and `waitforbuttonpress`, to wait for events. - This is implemented only for backends with GUIs. - """ - raise NotImplementedError + The event loop blocks until a callback function triggers + `stop_event_loop`, or *timeout* is reached. - def start_event_loop_default(self, timeout=0): - """ - Start an event loop. This is used to start a blocking event - loop so that interactive functions, such as ginput and - waitforbuttonpress, can wait for events. This should not be - confused with the main GUI event loop, which is always running - and has nothing to do with this. + If *timeout* is negative, never timeout. - This function provides default event loop functionality based - on time.sleep that is meant to be used until event loop - functions for each of the GUI backends can be written. As - such, it throws a deprecated warning. + Only interactive backends need to reimplement this method and it relies + on `flush_events` being properly implemented. - This call blocks until a callback function triggers - stop_event_loop() or *timeout* is reached. If *timeout* is - <=0, never timeout. + Interactive backends should implement this in a more native way. """ - str = "Using default event loop until function specific" - str += " to this GUI is implemented" - warnings.warn(str, mplDeprecation) - if timeout <= 0: timeout = np.inf timestep = 0.01 @@ -2485,15 +2457,19 @@ def start_event_loop_default(self, timeout=0): time.sleep(timestep) counter += 1 - def stop_event_loop_default(self): - """ - Stop an event loop. This is used to stop a blocking event - loop so that interactive functions, such as ginput and - waitforbuttonpress, can wait for events. + def stop_event_loop(self): + """Stop the current blocking event loop. + Interactive backends need to reimplement this to match + `start_event_loop` """ self._looping = False + start_event_loop_default = cbook.deprecated( + "2.1", name="start_event_loop_default")(start_event_loop) + stop_event_loop_default = cbook.deprecated( + "2.1", name="stop_event_loop_default")(stop_event_loop) + def key_press_handler(event, canvas, toolbar=None): """ diff --git a/lib/matplotlib/backends/backend_gtk.py b/lib/matplotlib/backends/backend_gtk.py index 757b2b7544c..d8d8387dca3 100644 --- a/lib/matplotlib/backends/backend_gtk.py +++ b/lib/matplotlib/backends/backend_gtk.py @@ -475,13 +475,6 @@ def flush_events(self): gtk.gdk.flush() gtk.gdk.threads_leave() - def start_event_loop(self,timeout): - FigureCanvasBase.start_event_loop_default(self,timeout) - start_event_loop.__doc__=FigureCanvasBase.start_event_loop_default.__doc__ - - def stop_event_loop(self): - FigureCanvasBase.stop_event_loop_default(self) - stop_event_loop.__doc__=FigureCanvasBase.stop_event_loop_default.__doc__ class FigureManagerGTK(FigureManagerBase): diff --git a/lib/matplotlib/backends/backend_gtk3.py b/lib/matplotlib/backends/backend_gtk3.py index a5f223a3875..df8cec6ec4a 100644 --- a/lib/matplotlib/backends/backend_gtk3.py +++ b/lib/matplotlib/backends/backend_gtk3.py @@ -332,14 +332,6 @@ def flush_events(self): Gdk.flush() Gdk.threads_leave() - def start_event_loop(self,timeout): - FigureCanvasBase.start_event_loop_default(self,timeout) - start_event_loop.__doc__=FigureCanvasBase.start_event_loop_default.__doc__ - - def stop_event_loop(self): - FigureCanvasBase.stop_event_loop_default(self) - stop_event_loop.__doc__=FigureCanvasBase.stop_event_loop_default.__doc__ - class FigureManagerGTK3(FigureManagerBase): """ diff --git a/lib/matplotlib/backends/backend_tkagg.py b/lib/matplotlib/backends/backend_tkagg.py index f6190d4f369..cb9971a00db 100644 --- a/lib/matplotlib/backends/backend_tkagg.py +++ b/lib/matplotlib/backends/backend_tkagg.py @@ -463,14 +463,6 @@ def new_timer(self, *args, **kwargs): def flush_events(self): self._master.update() - def start_event_loop(self,timeout): - FigureCanvasBase.start_event_loop_default(self,timeout) - start_event_loop.__doc__=FigureCanvasBase.start_event_loop_default.__doc__ - - def stop_event_loop(self): - FigureCanvasBase.stop_event_loop_default(self) - stop_event_loop.__doc__=FigureCanvasBase.stop_event_loop_default.__doc__ - class FigureManagerTkAgg(FigureManagerBase): """ diff --git a/lib/matplotlib/backends/backend_webagg.py b/lib/matplotlib/backends/backend_webagg.py index e39bf2cb2ba..a1468b39c30 100644 --- a/lib/matplotlib/backends/backend_webagg.py +++ b/lib/matplotlib/backends/backend_webagg.py @@ -59,17 +59,6 @@ def show(self): def new_timer(self, *args, **kwargs): return TimerTornado(*args, **kwargs) - def start_event_loop(self, timeout): - backend_bases.FigureCanvasBase.start_event_loop_default( - self, timeout) - start_event_loop.__doc__ = \ - backend_bases.FigureCanvasBase.start_event_loop_default.__doc__ - - def stop_event_loop(self): - backend_bases.FigureCanvasBase.stop_event_loop_default(self) - stop_event_loop.__doc__ = \ - backend_bases.FigureCanvasBase.stop_event_loop_default.__doc__ - class WebAggApplication(tornado.web.Application): initialized = False diff --git a/lib/matplotlib/backends/backend_webagg_core.py b/lib/matplotlib/backends/backend_webagg_core.py index d22d00704a9..7ef40187f6f 100644 --- a/lib/matplotlib/backends/backend_webagg_core.py +++ b/lib/matplotlib/backends/backend_webagg_core.py @@ -359,17 +359,6 @@ def handle_set_dpi_ratio(self, event): def send_event(self, event_type, **kwargs): self.manager._send_event(event_type, **kwargs) - def start_event_loop(self, timeout): - backend_bases.FigureCanvasBase.start_event_loop_default( - self, timeout) - start_event_loop.__doc__ = \ - backend_bases.FigureCanvasBase.start_event_loop_default.__doc__ - - def stop_event_loop(self): - backend_bases.FigureCanvasBase.stop_event_loop_default(self) - stop_event_loop.__doc__ = \ - backend_bases.FigureCanvasBase.stop_event_loop_default.__doc__ - _JQUERY_ICON_CLASSES = { 'home': 'ui-icon ui-icon-home', diff --git a/lib/matplotlib/pyplot.py b/lib/matplotlib/pyplot.py index 5c78047db80..79ee0f2decc 100644 --- a/lib/matplotlib/pyplot.py +++ b/lib/matplotlib/pyplot.py @@ -75,8 +75,7 @@ def _backend_selection(): loop, and if not switches to a compatible one. """ backend = rcParams['backend'] - if not rcParams['backend_fallback'] or \ - backend not in _interactive_bk: + if not rcParams['backend_fallback'] or backend not in _interactive_bk: return is_agg_backend = rcParams['backend'].endswith('Agg') if 'wx' in sys.modules and not backend in ('WX', 'WXAgg'): @@ -275,33 +274,24 @@ def pause(interval): """ Pause for *interval* seconds. - If there is an active figure it will be updated and displayed, - and the GUI event loop will run during the pause. + If there is an active figure, it will be updated and displayed before the + pause, and the GUI event loop (if any) will run during the pause. - If there is no active figure, or if a non-interactive backend - is in use, this executes time.sleep(interval). - - This can be used for crude animation. For more complex - animation, see :mod:`matplotlib.animation`. - - This function is experimental; its behavior may be changed - or extended in a future release. + This can be used for crude animation. For more complex animation, see + :mod:`matplotlib.animation`. + This function is experimental; its behavior may be changed or extended in a + future release. """ - backend = rcParams['backend'] - if backend in _interactive_bk: - figManager = _pylab_helpers.Gcf.get_active() - if figManager is not None: - canvas = figManager.canvas - if canvas.figure.stale: - canvas.draw_idle() - show(block=False) - canvas.start_event_loop(interval) - return - - # No on-screen figure is active, so sleep() is all we need. - import time - time.sleep(interval) + manager = _pylab_helpers.Gcf.get_active() + if manager is not None: + canvas = manager.canvas + if canvas.figure.stale: + canvas.draw_idle() + show(block=False) + canvas.start_event_loop(interval) + else: + time.sleep(interval) @docstring.copy_dedent(matplotlib.rc)