Skip to content

Commit 6389d14

Browse files
committed
Let the Javascript side control when to fetch new frames. draw_idle
sends a "draw" message to the browser. If the browser is not already waiting on another frame, it sends a "draw" message back to the server which then returns an actual frame. The nice thing about this approach is that it's completely timerless.
1 parent 68ca1a5 commit 6389d14

File tree

4 files changed

+20
-30
lines changed

4 files changed

+20
-30
lines changed

Diff for: examples/user_interfaces/embedding_webagg.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ def __init__(self, figure):
237237
http_server = tornado.httpserver.HTTPServer(application)
238238
http_server.listen(8080)
239239

240-
print("http://localhost:8080/")
240+
print("http://127.0.0.1:8080/")
241241
print("Press Ctrl+C to quit")
242242

243243
tornado.ioloop.IOLoop.instance().start()

Diff for: lib/matplotlib/backends/backend_webagg.py

-13
Original file line numberDiff line numberDiff line change
@@ -145,19 +145,6 @@ def show(self):
145145
# show the figure window
146146
show()
147147

148-
def draw_idle(self):
149-
if self._pending_draw is None:
150-
ioloop = tornado.ioloop.IOLoop.instance()
151-
self._pending_draw = ioloop.add_timeout(
152-
datetime.timedelta(milliseconds=50),
153-
self._draw_idle_callback)
154-
155-
def _draw_idle_callback(self):
156-
try:
157-
self.draw()
158-
finally:
159-
self._pending_draw = None
160-
161148
def new_timer(self, *args, **kwargs):
162149
return TimerTornado(*args, **kwargs)
163150

Diff for: lib/matplotlib/backends/backend_webagg_core.py

+4-14
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,6 @@ def __init__(self, *args, **kwargs):
6464
# sent to the clients will be a full frame.
6565
self._force_full = True
6666

67-
# Set to True when a drawing is in progress to prevent redraw
68-
# messages from piling up.
69-
self._pending_draw = None
70-
7167
def show(self):
7268
# show the figure window
7369
from matplotlib.pyplot import show
@@ -87,12 +83,7 @@ def draw(self):
8783
self.manager.refresh_all()
8884

8985
def draw_idle(self):
90-
# This is a poor-man's timer to make sure we don't send too
91-
# many frames.
92-
if (self._pending_draw is None or
93-
time.time() - self._pending_draw > 0.005):
94-
self.draw()
95-
self._pending_draw = time.time()
86+
self.send_event("draw")
9687

9788
def get_diff_image(self):
9889
if self._png_is_old:
@@ -167,7 +158,9 @@ def handle_event(self, event):
167158
# future, but for now the performance increase is enough
168159
# to justify it, even if the server does nothing with it.
169160
pass
170-
if e_type in ('button_press', 'button_release', 'motion_notify'):
161+
elif e_type == 'draw':
162+
self.draw()
163+
elif e_type in ('button_press', 'button_release', 'motion_notify'):
171164
x = event['x']
172165
y = event['y']
173166
y = self.get_renderer().height - y
@@ -210,9 +203,6 @@ def handle_event(self, event):
210203
def send_event(self, event_type, **kwargs):
211204
self.manager._send_event(event_type, **kwargs)
212205

213-
def new_timer(self, *args, **kwargs):
214-
return TimerTornado(*args, **kwargs)
215-
216206
def start_event_loop(self, timeout):
217207
backend_bases.FigureCanvasBase.start_event_loop_default(
218208
self, timeout)

Diff for: lib/matplotlib/backends/web_backend/mpl.js

+15-2
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ mpl.figure = function(figure_id, websocket, ondownload, parent_element) {
5454

5555
var fig = this;
5656

57+
this.waiting = false;
58+
5759
onopen_creator = function(fig) {
5860
return function () {
5961
fig.send_message("supports_binary", {value: fig.supports_binary});
@@ -65,6 +67,7 @@ mpl.figure = function(figure_id, websocket, ondownload, parent_element) {
6567
onload_creator = function(fig) {
6668
return function() {
6769
fig.context.drawImage(fig.imageObj, 0, 0);
70+
fig.waiting = false;
6871
};
6972
};
7073
this.imageObj.onload = onload_creator(fig);
@@ -218,6 +221,14 @@ mpl.figure.prototype.send_message = function(type, properties) {
218221
}
219222

220223

224+
mpl.figure.prototype.send_draw_message = function() {
225+
if (!this.waiting) {
226+
this.waiting = true;
227+
this.ws.send(JSON.stringify({type: "draw", figure_id: this.id}));
228+
}
229+
}
230+
231+
221232
mpl.figure.prototype._make_on_message_function = function(fig) {
222233
return function socket_on_message(evt) {
223234
if (fig.supports_binary) {
@@ -249,6 +260,10 @@ mpl.figure.prototype._make_on_message_function = function(fig) {
249260
var msg = JSON.parse(evt.data);
250261

251262
switch(msg['type']) {
263+
case 'draw':
264+
fig.send_draw_message();
265+
break;
266+
252267
case 'message':
253268
fig.message.textContent = msg['message'];
254269
break;
@@ -358,8 +373,6 @@ mpl.figure.prototype.mouse_event = function(event, name) {
358373

359374

360375
mpl.figure.prototype.key_event = function(event, name) {
361-
console.log("key_event: " + event);
362-
363376
/* Don't fire events just when a modifier is changed. Modifiers are
364377
sent along with other keys. */
365378
if (event.keyCode >= 16 && event.keyCode <= 20) {

0 commit comments

Comments
 (0)