From 25ee876375a1d98f9f925348a2578d40cc75cd0b Mon Sep 17 00:00:00 2001 From: Antony Lee Date: Wed, 16 Dec 2020 11:02:28 +0100 Subject: [PATCH] Cleanups to webagg & friends. FigureCanvasWebAgg and FigureCanvasNbAgg empty subclasses of FigureCanvasWebAggCore. They only differed in that WebAggCore did not define the (common) timer class, which is easily fixed (but the TimerTornado definition needs to be moved above the FigureCanvasWegAggCore definition), and that WebAgg explicitly redefined `show` to use the module's `show`, whereas WebAggCore's `show` uses `pyplot.show`... but `pyplot.show` is defined as calling the backend module's `show`, so it comes down to the same. Still it's useful for them to be subclasses rather than straight aliases, to keep the possibility of a canvas->manager mapping. No need to explicitly mark WebAggCore as `supports_blit`, as that's autodetected now (one can easily check that `FigureCanvasWebAggCore.supports_blit` is still True). Saving `pgf` to a BytesIO actually works fine nowadays, and can indeed by manually tested on WebAgg. --- lib/matplotlib/backends/backend_nbagg.py | 2 +- lib/matplotlib/backends/backend_webagg.py | 7 +- .../backends/backend_webagg_core.py | 75 +++++++++---------- 3 files changed, 39 insertions(+), 45 deletions(-) diff --git a/lib/matplotlib/backends/backend_nbagg.py b/lib/matplotlib/backends/backend_nbagg.py index 61db60accc62..8c9093fddc34 100644 --- a/lib/matplotlib/backends/backend_nbagg.py +++ b/lib/matplotlib/backends/backend_nbagg.py @@ -142,7 +142,7 @@ def remove_comm(self, comm_id): class FigureCanvasNbAgg(FigureCanvasWebAggCore): - _timer_cls = TimerTornado + pass class CommSocket: diff --git a/lib/matplotlib/backends/backend_webagg.py b/lib/matplotlib/backends/backend_webagg.py index 4400fe5234cb..7f43187ac65f 100644 --- a/lib/matplotlib/backends/backend_webagg.py +++ b/lib/matplotlib/backends/backend_webagg.py @@ -48,12 +48,7 @@ def run(self): class FigureCanvasWebAgg(core.FigureCanvasWebAggCore): - _timer_cls = TimerTornado - - def show(self): - # show the figure window - global show # placates pyflakes: created by @_Backend.export below - show() + pass class WebAggApplication(tornado.web.Application): diff --git a/lib/matplotlib/backends/backend_webagg_core.py b/lib/matplotlib/backends/backend_webagg_core.py index 0c1b1e17268a..192789cacf07 100644 --- a/lib/matplotlib/backends/backend_webagg_core.py +++ b/lib/matplotlib/backends/backend_webagg_core.py @@ -117,8 +117,43 @@ def _handle_key(key): return key +class TimerTornado(backend_bases.TimerBase): + def __init__(self, *args, **kwargs): + self._timer = None + super().__init__(*args, **kwargs) + + def _timer_start(self): + self._timer_stop() + if self._single: + ioloop = tornado.ioloop.IOLoop.instance() + self._timer = ioloop.add_timeout( + datetime.timedelta(milliseconds=self.interval), + self._on_timer) + else: + self._timer = tornado.ioloop.PeriodicCallback( + self._on_timer, + max(self.interval, 1e-6)) + self._timer.start() + + def _timer_stop(self): + if self._timer is None: + return + elif self._single: + ioloop = tornado.ioloop.IOLoop.instance() + ioloop.remove_timeout(self._timer) + else: + self._timer.stop() + self._timer = None + + def _timer_set_interval(self): + # Only stop and restart it if the timer has already been started + if self._timer is not None: + self._timer_stop() + self._timer_start() + + class FigureCanvasWebAggCore(backend_agg.FigureCanvasAgg): - supports_blit = True + _timer_cls = TimerTornado def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) @@ -478,8 +513,7 @@ def get_javascript(cls, stream=None): for filetype, ext in sorted(FigureCanvasWebAggCore. get_supported_filetypes_grouped(). items()): - if ext[0] != 'pgf': # pgf does not support BytesIO - extensions.append(ext[0]) + extensions.append(ext[0]) output.write("mpl.extensions = {0};\n\n".format( json.dumps(extensions))) @@ -499,41 +533,6 @@ def _send_event(self, event_type, **kwargs): s.send_json(payload) -class TimerTornado(backend_bases.TimerBase): - def __init__(self, *args, **kwargs): - self._timer = None - super().__init__(*args, **kwargs) - - def _timer_start(self): - self._timer_stop() - if self._single: - ioloop = tornado.ioloop.IOLoop.instance() - self._timer = ioloop.add_timeout( - datetime.timedelta(milliseconds=self.interval), - self._on_timer) - else: - self._timer = tornado.ioloop.PeriodicCallback( - self._on_timer, - max(self.interval, 1e-6)) - self._timer.start() - - def _timer_stop(self): - if self._timer is None: - return - elif self._single: - ioloop = tornado.ioloop.IOLoop.instance() - ioloop.remove_timeout(self._timer) - else: - self._timer.stop() - self._timer = None - - def _timer_set_interval(self): - # Only stop and restart it if the timer has already been started - if self._timer is not None: - self._timer_stop() - self._timer_start() - - @_Backend.export class _BackendWebAggCoreAgg(_Backend): FigureCanvas = FigureCanvasWebAggCore