8000 Merge pull request #2261 from mdboom/webagg-improvements · matplotlib/matplotlib@48fdef5 · GitHub
[go: up one dir, main page]

Skip to content

Commit 48fdef5

Browse files
committed
Merge pull request #2261 from mdboom/webagg-improvements
WebAgg performance improvements
2 parents 1614a0d + d7d6f15 commit 48fdef5

File tree

3 files changed

+28
-8
lines changed

3 files changed

+28
-8
lines changed

lib/matplotlib/backend_bases.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3125,7 +3125,7 @@ def draw(self):
31253125

31263126
for loc in locators:
31273127
loc.refresh()
3128-
self.canvas.draw()
3128+
self.canvas.draw_idle()
31293129

31303130
def _update_view(self):
31313131
"""Update the viewlim and position from the view and
@@ -3146,7 +3146,7 @@ def _update_view(self):
31463146
a.set_position(pos[i][0], 'original')
31473147
a.set_position(pos[i][1], 'active')
31483148

3149-
self.draw()
3149+
self.draw_idle()
31503150

31513151
def save_figure(self, *args):
31523152
"""Save the current figure"""

lib/matplotlib/backends/backend_webagg.py

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,6 @@ def handle_event(self, event):
253253
elif e_type == 'key_release':
254254
self.key_release_event(key)
255255
elif e_type == 'toolbar_button':
256-
print('Toolbar button pressed: ', event['name'])
257256
# TODO: Be more suspicious of the input
258257
getattr(self.toolbar, event['name'])()
259258
elif e_type == 'refresh':
@@ -296,8 +295,10 @@ def remove_web_socket(self, web_socket):
296295
self.web_sockets.remove(web_socket)
297296

298297
def refresh_all(self):
299-
for s in self.web_sockets:
300-
s.send_image()
298+
if self.web_sockets:
299+
diff = self.canvas.get_diff_image()
300+
for s in self.web_sockets:
301+
s.send_diff_image(diff)
301302

302303
def send_event(self, event_type, **kwargs):
303304
for s in self.web_sockets:
@@ -473,6 +474,8 @@ def open(self, fignum):
473474
_, _, w, h = manager.canvas.figure.bbox.bounds
474475
manager.resize(w, h)
475476
self.on_message('{"type":"refresh"}')
477+
if hasattr(self, 'set_nodelay'):
478+
self.set_nodelay(True)
476479

477480
def on_close(self):
478481
Gcf.get_fig_manager(self.fignum).remove_web_socket(self)
@@ -484,6 +487,15 @@ def on_message(self, message):
484487
# whole.
485488
if message['type'] == 'supports_binary':
486489
self.supports_binary = message['value']
490+
elif message['type'] == 'ack':
491+
# Network latency tends to decrease if traffic is
492+
# flowing in both directions. Therefore, the browser
493+
# sends back an "ack" message after each image frame
494+
# is received. This could also be used as a simple
495+
# sanity check in the future, but for now the
496+
# performance increase is enough to justify it, even
497+
# if the server does nothing with it.
498+
pass
487499
else:
488500
canvas = Gcf.get_fig_manager(self.fignum).canvas
489501
canvas.handle_event(message)
@@ -493,9 +505,7 @@ def send_event(self, event_type, **kwargs):
493505
payload.update(kwargs)
494506
self.write_message(json.dumps(payload))
495507

496-
def send_image(self):
497-
canvas = Gcf.get_fig_manager(self.fignum).canvas
498-
diff = canvas.get_diff_image()
508+
def send_diff_image(self, diff):
499509
if self.supports_binary:
500510
self.write_message(diff, binary=True)
501511
else:

lib/matplotlib/backends/web_backend/mpl.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,11 @@ figure.prototype.finalize = function (canvas_id_prefix, toolbar_id_prefix, messa
6666
onload_creator = function(fig) {return function() {fig.context.drawImage(fig.imageObj, 0, 0);};};
6767
this.imageObj.onload = onload_creator(fig);
6868

69+
70+
this.imageObj.onunload = function() {
71+
this.ws.close();
72+
}
73+
6974
this.ws.onmessage = gen_on_msg_fn(this);
7075
};
7176

@@ -88,11 +93,13 @@ function gen_on_msg_fn(fig)
8893
}
8994
fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(
9095
evt.data);
96+
fig.ws.send('{"type": "ack"}')
9197
return;
9298
}
9399
} else {
94100
if (evt.data.slice(0, 21) == "data:image/png;base64") {
95101
fig.imageObj.src = evt.data;
102+
fig.ws.send('{"type": "ack"}')
96103
return;
97104
}
98105
}
@@ -132,6 +139,9 @@ function gen_on_msg_fn(fig)
132139
fig.rubberband_canvas.width = size[0];
133140
fig.rubberband_canvas.height = size[1];
134141
fig.ws.send(JSON.stringify({type: 'refresh'}));
142+
fig.ws.send(JSON.stringify(
143+
{type: 'supports_binary',
144+
value: fig.supports_binary}));
135145
}
136146
break;
137147

0 commit comments

Comments
 (0)
0