88# way over a web socket.
99#
1010# - `backend_webagg.py` contains a concrete implementation of a basic
11- # application, implemented with tornado .
11+ # application, implemented with asyncio .
1212
13+ import asyncio
1314import datetime
1415from io import BytesIO , StringIO
1516import json
1920
2021import numpy as np
2122from PIL import Image
22- import tornado
2323
2424from matplotlib import _api , backend_bases , backend_tools
2525from matplotlib .backends import backend_agg
@@ -85,6 +85,8 @@ def __init__(self, *args, **kwargs):
8585 super ().__init__ (* args , ** kwargs )
8686
8787 def _timer_start (self ):
88+ import tornado
89+
8890 self ._timer_stop ()
8991 if self ._single :
9092 ioloop = tornado .ioloop .IOLoop .instance ()
@@ -98,6 +100,8 @@ def _timer_start(self):
98100 self ._timer .start ()
99101
100102 def _timer_stop (self ):
103+ import tornado
104+
101105 if self ._timer is None :
102106 return
103107 elif self ._single :
@@ -114,8 +118,43 @@ def _timer_set_interval(self):
114118 self ._timer_start ()
115119
116120
121+ class TimerAsyncio (backend_bases .TimerBase ):
122+ def __init__ (self , * args , ** kwargs ):
123+ self ._task = None
124+ super ().__init__ (* args , ** kwargs )
125+
126+ async def _timer_task (self , interval ):
127+ while True :
128+ try :
129+ await asyncio .sleep (interval )
130+ self ._on_timer ()
131+
132+ if self ._single :
133+ break
134+ except asyncio .CancelledError :
135+ break
136+
137+ def _timer_start (self ):
138+ self ._timer_stop ()
139+
140+ self ._task = asyncio .ensure_future (
141+ self ._timer_task (max (self .interval / 1_000. , 1e-6 ))
142+ )
143+
144+ def _timer_stop (self ):
145+ if self ._task is not None :
146+ self ._task .cancel ()
147+ self ._task = None
148+
149+ def _timer_set_interval (self ):
150+ # Only stop and restart it if the timer has already been started
151+ if self ._task is not None :
152+ self ._timer_stop ()
153+ self ._timer_start ()
154+
155+
117156class FigureCanvasWebAggCore (backend_agg .FigureCanvasAgg ):
118- _timer_cls = TimerTornado
157+ _timer_cls = TimerAsyncio
119158 # Webagg and friends having the right methods, but still
120159 # having bugs in practice. Do not advertise that it works until
121160 # we can debug this.
0 commit comments