diff --git a/lib/matplotlib/backends/backend_nbagg.py b/lib/matplotlib/backends/backend_nbagg.py index ab3f8267cb44..8e745c14a5bc 100644 --- a/lib/matplotlib/backends/backend_nbagg.py +++ b/lib/matplotlib/backends/backend_nbagg.py @@ -92,6 +92,7 @@ def connection_info(): 'forward': 'fa fa-arrow-right icon-arrow-right', 'zoom_to_rect': 'fa fa-square-o icon-check-empty', 'move': 'fa fa-arrows icon-move', + 'download': 'fa fa-icon-save icon-save', None: None } @@ -102,7 +103,8 @@ class NavigationIPy(NavigationToolbar2WebAgg): toolitems = [(text, tooltip_text, _FONT_AWESOME_CLASSES[image_file], name_of_method) for text, tooltip_text, image_file, name_of_method - in NavigationToolbar2.toolitems + in (NavigationToolbar2.toolitems + + (('Download', 'Download plot', 'download', 'download'),)) if image_file in _FONT_AWESOME_CLASSES] diff --git a/lib/matplotlib/backends/backend_webagg_core.py b/lib/matplotlib/backends/backend_webagg_core.py index 511d05d6eec5..32bb61258a3d 100644 --- a/lib/matplotlib/backends/backend_webagg_core.py +++ b/lib/matplotlib/backends/backend_webagg_core.py @@ -329,7 +329,7 @@ def release_zoom(self, event): def save_figure(self, *args): """Save the current figure""" - warnings.warn('"Save figure" not implemented in Web Backend') + self.canvas.send_event('save') class FigureManagerWebAgg(backend_bases.FigureManagerBase): diff --git a/lib/matplotlib/backends/web_backend/mpl.js b/lib/matplotlib/backends/web_backend/mpl.js index 086fc0f31bd8..cebc8d12b76d 100644 --- a/lib/matplotlib/backends/web_backend/mpl.js +++ b/lib/matplotlib/backends/web_backend/mpl.js @@ -283,6 +283,14 @@ mpl.figure.prototype.send_draw_message = function() { } } + +mpl.figure.prototype.handle_save = function(fig, msg) { + var format_dropdown = fig.format_dropdown; + var format = format_dropdown.options[format_dropdown.selectedIndex].value; + fig.ondownload(fig, format); +} + + mpl.figure.prototype.handle_resize = function(fig, msg) { var size = msg['size']; if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) { @@ -472,9 +480,7 @@ mpl.figure.prototype.key_event = function(event, name) { mpl.figure.prototype.toolbar_button_onclick = function(name) { if (name == 'download') { - var format_dropdown = this.format_dropdown; - var format = format_dropdown.options[format_dropdown.selectedIndex].value; - this.ondownload(this, format); + this.handle_save(this, null); } else { this.send_message("toolbar_button", {name: name}); } diff --git a/lib/matplotlib/backends/web_backend/nbagg_mpl.js b/lib/matplotlib/backends/web_backend/nbagg_mpl.js index 39fa4350765c..609f4e3a0b57 100644 --- a/lib/matplotlib/backends/web_backend/nbagg_mpl.js +++ b/lib/matplotlib/backends/web_backend/nbagg_mpl.js @@ -30,8 +30,12 @@ mpl.mpl_figure_comm = function(comm, msg) { var element = $("#" + id); var ws_proxy = comm_websocket_adapter(comm) + function ondownload(figure, format) { + window.open(figure.imageObj.src); + } + var fig = new mpl.figure(id, ws_proxy, - function() { }, + ondownload, element.get(0)); // Call onopen now - mpl needs it, as it is assuming we've passed it a real @@ -142,6 +146,11 @@ mpl.figure.prototype._canvas_extra_style = function(el){ } +mpl.figure.prototype.handle_save = function(fig, msg) { + fig.ondownload(fig, null); +} + + mpl.find_output_cell = function(html_output) { // Return the cell and output element which can be found *uniquely* in the notebook. // Note - this is a bit hacky, but it is done because the "notebook_saving.Notebook"