{
“cells”: [
{

“cell_type”: “markdown”, “metadata”: {}, “source”: [

“# Custimizing the Controlsn”, “n”, “Here we’ll like how to manipulate the `timeline_slider` and the `toggle` button.n”, “n”, “The interactive controls can be make using the `controls()` method of the animation class, as in the getting started tutorial, but this method is a wrapper around the `toggle` and `timeline_slider` methods.n”, “n”, “First, we need from imports and data to animate.”

]

}, {

“cell_type”: “code”, “execution_count”: 1, “metadata”: {}, “outputs”: [], “source”: [

“%matplotlib notebookn”, “import numpy as npn”, “import matplotlib.pyplot as pltn”, “import animatplot as amp”

]

}, {

“cell_type”: “code”, “execution_count”: 2, “metadata”: {}, “outputs”: [], “source”: [

“x = np.linspace(0, 1, 50)n”, “t = np.linspace(0, 1, 20)n”, “n”, “X, T = np.meshgrid(x, t)n”, “Y = np.sin(2 * np.pi * (X + T))”

]

}, {

“cell_type”: “raw”, “metadata”: {

“raw_mimetype”: “text/restructuredtext”

}, “source”: [

“.. currentmodule:: animatplotn”, “n”, “.. automethod:: Animation.togglen”, “ :noindex:n”, “n”, “.. automethod:: Animation.timeline_slidern”, “ :noindex:n”, “n”, “.. automethod:: Animation.controlsn”, “ :noindex:”

]

}, {

“cell_type”: “markdown”, “metadata”: {}, “source”: [

Now to make the animationn”, “n”, “By specifying the `ax` parameter, we can change the position of either the toggle or the timeline_slider.n”, “n”, “We use `color` to change the color of the slider, and `valfmt` to change how the time is displayed.n”, “n”, “Let’s create our block, then create the controls at the top of the animation.”

]

}, {

“cell_type”: “code”, “execution_count”: 3, “metadata”: {}, “outputs”: [

{
“data”: {
“application/javascript”: [

“/* Put everything inside the global mpl namespace /n”, “window.mpl = {};n”, “n”, “n”, “mpl.get_websocket_type = function() {n”, “ if (typeof(WebSocket) !== ‘undefined’) {n”, “ return WebSocket;n”, “ } else if (typeof(MozWebSocket) !== ‘undefined’) {n”, “ return MozWebSocket;n”, “ } else {n”, “ alert(‘Your browser does not have WebSocket support.’ +n”, “ ‘Please try Chrome, Safari or Firefox ≥ 6. ‘ +n”, “ ‘Firefox 4 and 5 are also supported but you ‘ +n”, “ ‘have to enable WebSockets in about:config.’);n”, “ };n”, “}n”, “n”, “mpl.figure = function(figure_id, websocket, ondownload, parent_element) {n”, “ this.id = figure_id;n”, “n”, “ this.ws = websocket;n”, “n”, “ this.supports_binary = (this.ws.binaryType != undefined);n”, “n”, “ if (!this.supports_binary) {n”, “ var warnings = document.getElementById("mpl-warnings");n”, “ if (warnings) {n”, “ warnings.style.display = ‘block’;n”, “ warnings.textContent = (n”, “ "This browser does not support binary websocket messages. " +n”, “ "Performance may be slow.");n”, “ }n”, “ }n”, “n”, “ this.imageObj = new Image();n”, “n”, “ this.context = undefined;n”, “ this.message = undefined;n”, “ this.canvas = undefined;n”, “ this.rubberband_canvas = undefined;n”, “ this.rubberband_context = undefined;n”, “ this.format_dropdown = undefined;n”, “n”, “ this.image_mode = ‘full’;n”, “n”, “ this.root = $(‘<div/>’);n”, “ this._root_extra_style(this.root)n”, “ this.root.attr(‘style’, ‘display: inline-block’);n”, “n”, “ $(parent_element).append(this.root);n”, “n”, “ this._init_header(this);n”, “ this._init_canvas(this);n”, “ this._init_toolbar(this);n”, “n”, “ var fig = this;n”, “n”, “ this.waiting = false;n”, “n”, “ this.ws.onopen = function () {n”, “ fig.send_message("supports_binary", {value: fig.supports_binary});n”, “ fig.send_message("send_image_mode", {});n”, “ if (mpl.ratio != 1) {n”, “ fig.send_message("set_dpi_ratio", {‘dpi_ratio’: mpl.ratio});n”, “ }n”, “ fig.send_message("refresh", {});n”, “ }n”, “n”, “ this.imageObj.onload = function() {n”, “ if (fig.image_mode == ‘full’) {n”, “ // Full images could contain transparency (where diff imagesn”, “ // almost always do), so we need to clear the canvas so thatn”, “ // there is no ghosting.n”, “ fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);n”, “ }n”, “ fig.context.drawImage(fig.imageObj, 0, 0);n”, “ };n”, “n”, “ this.imageObj.onunload = function() {n”, “ fig.ws.close();n”, “ }n”, “n”, “ this.ws.onmessage = this._make_on_message_function(this);n”, “n”, “ this.ondownload = ondownload;n”, “}n”, “n”, “mpl.figure.prototype._init_header = function() {n”, “ var titlebar = $(n”, “ ‘<div class="ui-dialog-titlebar ui-widget-header ui-corner-all ‘ +n”, “ ‘ui-helper-clearfix"/>’);n”, “ var titletext = $(n”, “ ‘<div class="ui-dialog-title" style="width: 100%; ‘ +n”, “ ‘text-align: center; padding: 3px;"/>’);n”, “ titlebar.append(titletext)n”, “ this.root.append(titlebar);n”, “ this.header = titletext[0];n”, “}n”, “n”, “n”, “n”, “mpl.figure.prototype._canvas_extra_style = function(canvas_div) {n”, “n”, “}n”, “n”, “n”, “mpl.figure.prototype._root_extra_style = function(canvas_div) {n”, “n”, “}n”, “n”, “mpl.figure.prototype._init_canvas = function() {n”, “ var fig = this;n”, “n”, “ var canvas_div = $(‘<div/>’);n”, “n”, “ canvas_div.attr(‘style’, ‘position: relative; clear: both; outline: 0’);n”, “n”, “ function canvas_keyboard_event(event) {n”, “ return fig.key_event(event, event[‘data’]);n”, “ }n”, “n”, “ canvas_div.keydown(‘key_press’, canvas_keyboard_event);n”, “ canvas_div.keyup(‘key_release’, canvas_keyboard_event);n”, “ this.canvas_div = canvas_divn”, “ this._canvas_extra_style(canvas_div)n”, “ this.root.append(canvas_div);n”, “n”, “ var canvas = $(‘<canvas/>’);n”, “ canvas.addClass(‘mpl-canvas’);n”, “ canvas.attr(‘style’, "left: 0; top: 0; z-index: 0; outline: 0")n”, “n”, “ this.canvas = canvas[0];n”, “ this.context = canvas[0].getContext("2d");n”, “n”, “ var backingStore = this.context.backingStorePixelRatio ||n”, “tthis.context.webkitBackingStorePixelRatio ||n”, “tthis.context.mozBackingStorePixelRatio ||n”, “tthis.context.msBackingStorePixelRatio ||n”, “tthis.context.oBackingStorePixelRatio ||n”, “tthis.context.backingStorePixelRatio || 1;n”, “n”, “ mpl.ratio = (window.devicePixelRatio || 1) / backingStore;n”, “n”, “ var rubberband = $(‘<canvas/>’);n”, “ rubberband.attr(‘style’, "position: absolute; left: 0; top: 0; z-index: 1;")n”, “n”, “ var pass_mouse_events = true;n”, “n”, “ canvas_div.resizable({n”, “ start: function(event, ui) {n”, “ pass_mouse_events = false;n”, “ },n”, “ resize: function(event, ui) {n”, “ fig.request_resize(ui.size.width, ui.size.height);n”, “ },n”, “ stop: function(event, ui) {n”, “ pass_mouse_events = true;n”, “ fig.request_resize(ui.size.width, ui.size.height);n”, “ },n”, “ });n”, “n”, “ function mouse_event_fn(event) {n”, “ if (pass_mouse_events)n”, “ return fig.mouse_event(event, event[‘data’]);n”, “ }n”, “n”, “ rubberband.mousedown(‘button_press’, mouse_event_fn);n”, “ rubberband.mouseup(‘button_release’, mouse_event_fn);n”, “ // Throttle sequential mouse events to 1 every 20ms.n”, “ rubberband.mousemove(‘motion_notify’, mouse_event_fn);n”, “n”, “ rubberband.mouseenter(‘figure_enter’, mouse_event_fn);n”, “ rubberband.mouseleave(‘figure_leave’, mouse_event_fn);n”, “n”, “ canvas_div.on("wheel", function (event) {n”, “ event = event.originalEvent;n”, “ event[‘data’] = ‘scroll’n”, “ if (event.deltaY < 0) {n”, “ event.step = 1;n”, “ } else {n”, “ event.step = -1;n”, “ }n”, “ mouse_event_fn(event);n”, “ });n”, “n”, “ canvas_div.append(canvas);n”, “ canvas_div.append(rubberband);n”, “n”, “ this.rubberband = rubberband;n”, “ this.rubberband_canvas = rubberband[0];n”, “ this.rubberband_context = rubberband[0].getContext("2d");n”, “ this.rubberband_context.strokeStyle = "#000000";n”, “n”, “ this._resize_canvas = function(width, height) {n”, “ // Keep the size of the canvas, canvas container, and rubber bandn”, “ // canvas in synch.n”, “ canvas_div.css(‘width’, width)n”, “ canvas_div.css(‘height’, height)n”, “n”, “ canvas.attr(‘width’, width * mpl.ratio);n”, “ canvas.attr(‘height’, height * mpl.ratio);n”, “ canvas.attr(‘style’, ‘width: ‘ + width + ‘px; height: ‘ + height + ‘px;’);n”, “n”, “ rubberband.attr(‘width’, width);n”, “ rubberband.attr(‘height’, height);n”, “ }n”, “n”, “ // Set the figure to an initial 600x600px, this will subsequently be updatedn”, “ // upon first draw.n”, “ this._resize_canvas(600, 600);n”, “n”, “ // Disable right mouse context menu.n”, “ $(this.rubberband_canvas).bind("contextmenu",function(e){n”, “ return false;n”, “ });n”, “n”, “ function set_focus () {n”, “ canvas.focus();n”, “ canvas_div.focus();n”, “ }n”, “n”, “ window.setTimeout(set_focus, 100);n”, “}n”, “n”, “mpl.figure.prototype._init_toolbar = function() {n”, “ var fig = this;n”, “n”, “ var nav_element = $(‘<div/>’)n”, “ nav_element.attr(‘style’, ‘width: 100%’);n”, “ this.root.append(nav_element);n”, “n”, “ // Define a callback function for later on.n”, “ function toolbar_event(event) {n”, “ return fig.toolbar_button_onclick(event[‘data’]);n”, “ }n”, “ function toolbar_mouse_event(event) {n”, “ return fig.toolbar_button_onmouseover(event[‘data’]);n”, “ }n”, “n”, “ for(var toolbar_ind in mpl.toolbar_items) {n”, “ var name = mpl.toolbar_items[toolbar_ind][0];n”, “ var tooltip = mpl.toolbar_items[toolbar_ind][1];n”, “ var image = mpl.toolbar_items[toolbar_ind][2];n”, “ var method_name = mpl.toolbar_items[toolbar_ind][3];n”, “n”, “ if (!name) {n”, “ // put a spacer in here.n”, “ continue;n”, “ }n”, “ var button = $(‘<button/>’);n”, “ button.addClass(‘ui-button ui-widget ui-state-default ui-corner-all ‘ +n”, “ ‘ui-button-icon-only’);n”, “ button.attr(‘role’, ‘button’);n”, “ button.attr(‘aria-disabled’, ‘false’);n”, “ button.click(method_name, toolbar_event);n”, “ button.mouseover(tooltip, toolbar_mouse_event);n”, “n”, “ var icon_img = $(‘<span/>’);n”, “ icon_img.addClass(‘ui-button-icon-primary ui-icon’);n”, “ icon_img.addClass(image);n”, “ icon_img.addClass(‘ui-corner-all’);n”, “n”, “ var tooltip_span = $(‘<span/>’);n”, “ tooltip_span.addClass(‘ui-button-text’);n”, “ tooltip_span.html(tooltip);n”, “n”, “ button.append(icon_img);n”, “ button.append(tooltip_span);n”, “n”, “ nav_element.append(button);n”, “ }n”, “n”, “ var fmt_picker_span = $(‘<span/>’);n”, “n”, “ var fmt_picker = $(‘<select/>’);n”, “ fmt_picker.addClass(‘mpl-toolbar-option ui-widget ui-widget-content’);n”, “ fmt_picker_span.append(fmt_picker);n”, “ nav_element.append(fmt_picker_span);n”, “ this.format_dropdown = fmt_picker[0];n”, “n”, “ for (var ind in mpl.extensions) {n”, “ var fmt = mpl.extensions[ind];n”, “ var option = $(n”, “ ‘<option/>’, {selected: fmt === mpl.default_extension}).html(fmt);n”, “ fmt_picker.append(option)n”, “ }n”, “n”, “ // Add hover states to the ui-buttonsn”, “ $( ".ui-button" ).hover(n”, “ function() { $(this).addClass("ui-state-hover");},n”, “ function() { $(this).removeClass("ui-state-hover");}n”, “ );n”, “n”, “ var status_bar = $(‘<span class="mpl-message"/>’);n”, “ nav_element.append(status_bar);n”, “ this.message = status_bar[0];n”, “}n”, “n”, “mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {n”, “ // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,n”, “ // which will in turn request a refresh of the image.n”, “ this.send_message(‘resize’, {‘width’: x_pixels, ‘height’: y_pixels});n”, “}n”, “n”, “mpl.figure.prototype.send_message = function(type, properties) {n”, “ properties[‘type’] = type;n”, “ properties[‘figure_id’] = this.id;n”, “ this.ws.send(JSON.stringify(properties));n”, “}n”, “n”, “mpl.figure.prototype.send_draw_message = function() {n”, “ if (!this.waiting) {n”, “ this.waiting = true;n”, “ this.ws.send(JSON.stringify({type: "draw", figure_id: this.id}));n”, “ }n”, “}n”, “n”, “n”, “mpl.figure.prototype.handle_save = function(fig, msg) {n”, “ var format_dropdown = fig.format_dropdown;n”, “ var format = format_dropdown.options[format_dropdown.selectedIndex].value;n”, “ fig.ondownload(fig, format);n”, “}n”, “n”, “n”, “mpl.figure.prototype.handle_resize = function(fig, msg) {n”, “ var size = msg[‘size’];n”, “ if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {n”, “ fig._resize_canvas(size[0], size[1]);n”, “ fig.send_message("refresh", {});n”, “ };n”, “}n”, “n”, “mpl.figure.prototype.handle_rubberband = function(fig, msg) {n”, “ var x0 = msg[‘x0’] / mpl.ratio;n”, “ var y0 = (fig.canvas.height - msg[‘y0’]) / mpl.ratio;n”, “ var x1 = msg[‘x1’] / mpl.ratio;n”, “ var y1 = (fig.canvas.height - msg[‘y1’]) / mpl.ratio;n”, “ x0 = Math.floor(x0) + 0.5;n”, “ y0 = Math.floor(y0) + 0.5;n”, “ x1 = Math.floor(x1) + 0.5;n”, “ y1 = Math.floor(y1) + 0.5;n”, “ var min_x = Math.min(x0, x1);n”, “ var min_y = Math.min(y0, y1);n”, “ var width = Math.abs(x1 - x0);n”, “ var height = Math.abs(y1 - y0);n”, “n”, “ fig.rubberband_context.clearRect(n”, “ 0, 0, fig.canvas.width, fig.canvas.height);n”, “n”, “ fig.rubberband_context.strokeRect(min_x, min_y, width, height);n”, “}n”, “n”, “mpl.figure.prototype.handle_figure_label = function(fig, msg) {n”, “ // Updates the figure title.n”, “ fig.header.textContent = msg[‘label’];n”, “}n”, “n”, “mpl.figure.prototype.handle_cursor = function(fig, msg) {n”, “ var cursor = msg[‘cursor’];n”, “ switch(cursor)n”, “ {n”, “ case 0:n”, “ cursor = ‘pointer’;n”, “ break;n”, “ case 1:n”, “ cursor = ‘default’;n”, “ break;n”, “ case 2:n”, “ cursor = ‘crosshair’;n”, “ break;n”, “ case 3:n”, “ cursor = ‘move’;n”, “ break;n”, “ }n”, “ fig.rubberband_canvas.style.cursor = cursor;n”, “}n”, “n”, “mpl.figure.prototype.handle_message = function(fig, msg) {n”, “ fig.message.textContent = msg[‘message’];n”, “}n”, “n”, “mpl.figure.prototype.handle_draw = function(fig, msg) {n”, “ // Request the server to send over a new figure.n”, “ fig.send_draw_message();n”, “}n”, “n”, “mpl.figure.prototype.handle_image_mode = function(fig, msg) {n”, “ fig.image_mode = msg[‘mode’];n”, “}n”, “n”, “mpl.figure.prototype.updated_canvas_event = function() {n”, “ // Called whenever the canvas gets updated.n”, “ this.send_message("ack", {});n”, “}n”, “n”, “// A function to construct a web socket function for onmessage handling.n”, “// Called in the figure constructor.n”, “mpl.figure.prototype._make_on_message_function = function(fig) {n”, “ return function socket_on_message(evt) {n”, “ if (evt.data instanceof Blob) {n”, “ / FIXME: We get "Resource interpreted as Image butn”, “ * transferred with MIME type text/plain:" errors onn”, “ * Chrome. But how to set the MIME type? It doesn’t seemn”, “ * to be part of the websocket stream /n”, “ evt.data.type = "image/png";n”, “n”, “ / Free the memory for the previous frames /n”, “ if (fig.imageObj.src) {n”, “ (window.URL || window.webkitURL).revokeObjectURL(n”, “ fig.imageObj.src);n”, “ }n”, “n”, “ fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(n”, “ evt.data);n”, “ fig.updated_canvas_event();n”, “ fig.waiting = false;n”, “ return;n”, “ }n”, “ else if (typeof evt.data === ‘string’ && evt.data.slice(0, 21) == "data:image/png;base64") {n”, “ fig.imageObj.src = evt.data;n”, “ fig.updated_canvas_event();n”, “ fig.waiting = false;n”, “ return;n”, “ }n”, “n”, “ var msg = JSON.parse(evt.data);n”, “ var msg_type = msg[‘type’];n”, “n”, “ // Call the "handle_{type}" callback, which takesn”, “ // the figure and JSON message as its only arguments.n”, “ try {n”, “ var callback = fig["handle_" + msg_type];n”, “ } catch (e) {n”, “ console.log("No handler for the ‘" + msg_type + "’ message type: ", msg);n”, “ return;n”, “ }n”, “n”, “ if (callback) {n”, “ try {n”, “ // console.log("Handling ‘" + msg_type + "’ message: ", msg);n”, “ callback(fig, msg);n”, “ } catch (e) {n”, “ console.log("Exception inside the ‘handler_" + msg_type + "’ callback:", e, e.stack, msg);n”, “ }n”, “ }n”, “ };n”, “}n”, “n”, “// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvasn”, “mpl.findpos = function(e) {n”, “ //this section is from http://www.quirksmode.org/js/events_properties.htmln”, “ var targ;n”, “ if (!e)n”, “ e = window.event;n”, “ if (e.target)n”, “ targ = e.target;n”, “ else if (e.srcElement)n”, “ targ = e.srcElement;n”, “ if (targ.nodeType == 3) // defeat Safari bugn”, “ targ = targ.parentNode;n”, “n”, “ // jQuery normalizes the pageX and pageYn”, “ // pageX,Y are the mouse positions relative to the documentn”, “ // offset() returns the position of the element relative to the documentn”, “ var x = e.pageX - $(targ).offset().left;n”, “ var y = e.pageY - $(targ).offset().top;n”, “n”, “ return {"x": x, "y": y};n”, “};n”, “n”, “/n”, “ * return a copy of an object with only non-object keysn”, “ * we need this to avoid circular referencesn”, “ * http://stackoverflow.com/a/24161582/3208463n”, “ /n”, “function simpleKeys (original) {n”, “ return Object.keys(original).reduce(function (obj, key) {n”, “ if (typeof original[key] !== ‘object’)n”, “ obj[key] = original[key]n”, “ return obj;n”, “ }, {});n”, “}n”, “n”, “mpl.figure.prototype.mouse_event = function(event, name) {n”, “ var canvas_pos = mpl.findpos(event)n”, “n”, “ if (name === ‘button_press’)n”, “ {n”, “ this.canvas.focus();n”, “ this.canvas_div.focus();n”, “ }n”, “n”, “ var x = canvas_pos.x * mpl.ratio;n”, “ var y = canvas_pos.y * mpl.ratio;n”, “n”, “ this.send_message(name, {x: x, y: y, button: event.button,n”, “ step: event.step,n”, “ guiEvent: simpleKeys(event)});n”, “n”, “ / This prevents the web browser from automatically changing ton”, “ * the text insertion cursor when the button is pressed. We wantn”, “ * to control all of the cursor setting manually through then”, “ * ‘cursor’ event from matplotlib /n”, “ event.preventDefault();n”, “ return false;n”, “}n”, “n”, “mpl.figure.prototype._key_event_extra = function(event, name) {n”, “ // Handle any extra behaviour associated with a key eventn”, “}n”, “n”, “mpl.figure.prototype.key_event = function(event, name) {n”, “n”, “ // Prevent repeat eventsn”, “ if (name == ‘key_press’)n”, “ {n”, “ if (event.which === this._key)n”, “ return;n”, “ elsen”, “ this._key = event.which;n”, “ }n”, “ if (name == ‘key_release’)n”, “ this._key = null;n”, “n”, “ var value = ‘’;n”, “ if (event.ctrlKey && event.which != 17)n”, “ value += "ctrl+";n”, “ if (event.altKey && event.which != 18)n”, “ value += "alt+";n”, “ if (event.shiftKey && event.which != 16)n”, “ value += "shift+";n”, “n”, “ value += ‘k’;n”, “ value += event.which.toString();n”, “n”, “ this._key_event_extra(event, name);n”, “n”, “ this.send_message(name, {key: value,n”, “ guiEvent: simpleKeys(event)});n”, “ return false;n”, “}n”, “n”, “mpl.figure.prototype.toolbar_button_onclick = function(name) {n”, “ if (name == ‘download’) {n”, “ this.handle_save(this, null);n”, “ } else {n”, “ this.send_message("toolbar_button", {name: name});n”, “ }n”, “};n”, “n”, “mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {n”, “ this.message.textContent = tooltip;n”, “};n”, “mpl.toolbar_items = [["Home", "Reset original view", "fa fa-home icon-home", "home"], ["Back", "Back to previous view", "fa fa-arrow-left icon-arrow-left", "back"], ["Forward", "Forward to next view", "fa fa-arrow-right icon-arrow-right", "forward"], ["", "", "", ""], ["Pan", "Pan axes with left mouse, zoom with right", "fa fa-arrows icon-move", "pan"], ["Zoom", "Zoom to rectangle", "fa fa-square-o icon-check-empty", "zoom"], ["", "", "", ""], ["Download", "Download plot", "fa fa-floppy-o icon-save", "download"]];n”, “n”, “mpl.extensions = ["eps", "jpeg", "pdf", "png", "ps", "raw", "svg", "tif"];n”, “n”, “mpl.default_extension = "png";var comm_websocket_adapter = function(comm) {n”, “ // Create a "websocket"-like object which calls the given IPython commn”, “ // object with the appropriate methods. Currently this is a non binaryn”, “ // socket, so there is still some room for performance tuning.n”, “ var ws = {};n”, “n”, “ ws.close = function() {n”, “ comm.close()n”, “ };n”, “ ws.send = function(m) {n”, “ //console.log(‘sending’, m);n”, “ comm.send(m);n”, “ };n”, “ // Register the callback with on_msg.n”, “ comm.on_msg(function(msg) {n”, “ //console.log(‘receiving’, msg[‘content’][‘data’], msg);n”, “ // Pass the mpl event to the overridden (by mpl) onmessage function.n”, “ ws.onmessage(msg[‘content’][‘data’])n”, “ });n”, “ return ws;n”, “}n”, “n”, “mpl.mpl_figure_comm = function(comm, msg) {n”, “ // This is the function which gets called when the mpl processn”, “ // starts-up an IPython Comm through the "matplotlib" channel.n”, “n”, “ var id = msg.content.data.id;n”, “ // Get hold of the div created by the display call when the Commn”, “ // socket was opened in Python.n”, “ var element = $("#" + id);n”, “ var ws_proxy = comm_websocket_adapter(comm)n”, “n”, “ function ondownload(figure, format) {n”, “ window.open(figure.imageObj.src);n”, “ }n”, “n”, “ var fig = new mpl.figure(id, ws_proxy,n”, “ ondownload,n”, “ element.get(0));n”, “n”, “ // Call onopen now - mpl needs it, as it is assuming we’ve passed it a realn”, “ // web socket which is closed, not our websocket->open comm proxy.n”, “ ws_proxy.onopen();n”, “n”, “ fig.parent_element = element.get(0);n”, “ fig.cell_info = mpl.find_output_cell("<div id=’" + id + "’></div>");n”, “ if (!fig.cell_info) {n”, “ console.error("Failed to find cell for figure", id, fig);n”, “ return;n”, “ }n”, “n”, “ var output_index = fig.cell_info[2]n”, “ var cell = fig.cell_info[0];n”, “n”, “};n”, “n”, “mpl.figure.prototype.handle_close = function(fig, msg) {n”, “ var width = fig.canvas.width/mpl.ration”, “ fig.root.unbind(‘remove’)n”, “n”, “ // Update the output cell to use the data from the current canvas.n”, “ fig.push_to_output();n”, “ var dataURL = fig.canvas.toDataURL();n”, “ // Re-enable the keyboard manager in IPython - without this line, in FF,n”, “ // the notebook keyboard shortcuts fail.n”, “ IPython.keyboard_manager.enable()n”, “ $(fig.parent_element).html(‘<img src="’ + dataURL + ‘" width="’ + width + ‘">’);n”, “ fig.close_ws(fig, msg);n”, “}n”, “n”, “mpl.figure.prototype.close_ws = function(fig, msg){n”, “ fig.send_message(‘closing’, msg);n”, “ // fig.ws.close()n”, “}n”, “n”, “mpl.figure.prototype.push_to_output = function(remove_interactive) {n”, “ // Turn the data on the canvas into data in the output cell.n”, “ var width = this.canvas.width/mpl.ration”, “ var dataURL = this.canvas.toDataURL();n”, “ this.cell_info[1][‘text/html’] = ‘<img src="’ + dataURL + ‘" width="’ + width + ‘">’;n”, “}n”, “n”, “mpl.figure.prototype.updated_canvas_event = function() {n”, “ // Tell IPython that the notebook contents must change.n”, “ IPython.notebook.set_dirty(true);n”, “ this.send_message("ack", {});n”, “ var fig = this;n”, “ // Wait a second, then push the new image to the DOM son”, “ // that it is saved nicely (might be nice to debounce this).n”, “ setTimeout(function () { fig.push_to_output() }, 1000);n”, “}n”, “n”, “mpl.figure.prototype._init_toolbar = function() {n”, “ var fig = this;n”, “n”, “ var nav_element = $(‘<div/>’)n”, “ nav_element.attr(‘style’, ‘width: 100%’);n”, “ this.root.append(nav_element);n”, “n”, “ // Define a callback function for later on.n”, “ function toolbar_event(event) {n”, “ return fig.toolbar_button_onclick(event[‘data’]);n”, “ }n”, “ function toolbar_mouse_event(event) {n”, “ return fig.toolbar_button_onmouseover(event[‘data’]);n”, “ }n”, “n”, “ for(var toolbar_ind in mpl.toolbar_items){n”, “ var name = mpl.toolbar_items[toolbar_ind][0];n”, “ var tooltip = mpl.toolbar_items[toolbar_ind][1];n”, “ var image = mpl.toolbar_items[toolbar_ind][2];n”, “ var method_name = mpl.toolbar_items[toolbar_ind][3];n”, “n”, “ if (!name) { continue; };n”, “n”, “ var button = $(‘<button class="btn btn-default" href="#" title="’ + name + ‘"><i class="fa ‘ + image + ‘ fa-lg"></i></button>’);n”, “ button.click(method_name, toolbar_event);n”, “ button.mouseover(tooltip, toolbar_mouse_event);n”, “ nav_element.append(button);n”, “ }n”, “n”, “ // Add the status bar.n”, “ var status_bar = $(‘<span class="mpl-message" style="text-align:right; float: right;"/>’);n”, “ nav_element.append(status_bar);n”, “ this.message = status_bar[0];n”, “n”, “ // Add the close button to the window.n”, “ var buttongrp = $(‘<div class="btn-group inline pull-right"></div>’);n”, “ var button = $(‘<button class="btn btn-mini btn-primary" href="#" title="Stop Interaction"><i class="fa fa-power-off icon-remove icon-large"></i></button>’);n”, “ button.click(function (evt) { fig.handle_close(fig, {}); } );n”, “ button.mouseover(‘Stop Interaction’, toolbar_mouse_event);n”, “ buttongrp.append(button);n”, “ var titlebar = this.root.find($(‘.ui-dialog-titlebar’));n”, “ titlebar.prepend(buttongrp);n”, “}n”, “n”, “mpl.figure.prototype._root_extra_style = function(el){n”, “ var fig = thisn”, “ el.on("remove", function(){n”, “tfig.close_ws(fig, {});n”, “ });n”, “}n”, “n”, “mpl.figure.prototype._canvas_extra_style = function(el){n”, “ // this is important to make the div ‘focusablen”, “ el.attr(‘tabindex’, 0)n”, “ // reach out to IPython and tell the keyboard manager to turn it’s selfn”, “ // off when our div gets focusn”, “n”, “ // location in version 3n”, “ if (IPython.notebook.keyboard_manager) {n”, “ IPython.notebook.keyboard_manager.register_events(el);n”, “ }n”, “ else {n”, “ // location in version 2n”, “ IPython.keyboard_manager.register_events(el);n”, “ }n”, “n”, “}n”, “n”, “mpl.figure.prototype._key_event_extra = function(event, name) {n”, “ var manager = IPython.notebook.keyboard_manager;n”, “ if (!manager)n”, “ manager = IPython.keyboard_manager;n”, “n”, “ // Check for shift+entern”, “ if (event.shiftKey && event.which == 13) {n”, “ this.canvas_div.blur();n”, “ event.shiftKey = false;n”, “ // Send a "J" for go to next celln”, “ event.which = 74;n”, “ event.keyCode = 74;n”, “ manager.command_mode();n”, “ manager.handle_keydown(event);n”, “ }n”, “}n”, “n”, “mpl.figure.prototype.handle_save = function(fig, msg) {n”, “ fig.ondownload(fig, null);n”, “}n”, “n”, “n”, “mpl.find_output_cell = function(html_output) {n”, “ // Return the cell and output element which can be found *uniquely in the notebook.n”, “ // Note - this is a bit hacky, but it is done because the "notebook_saving.Notebook"n”, “ // IPython event is triggered only after the cells have been serialised, which forn”, “ // our purposes (turning an active figure into a static one), is too late.n”, “ var cells = IPython.notebook.get_cells();n”, “ var ncells = cells.length;n”, “ for (var i=0; i<ncells; i++) {n”, “ var cell = cells[i];n”, “ if (cell.cell_type === ‘code’){n”, “ for (var j=0; j<cell.output_area.outputs.length; j++) {n”, “ var data = cell.output_area.outputs[j];n”, “ if (data.data) {n”, “ // IPython >= 3 moved mimebundle to data attribute of outputn”, “ data = data.data;n”, “ }n”, “ if (data[‘text/html’] == html_output) {n”, “ return [cell, data, j];n”, “ }n”, “ }n”, “ }n”, “ }n”, “}n”, “n”, “// Register the function which deals with the matplotlib target/channel.n”, “// The kernel may be null if the page has been refreshed.n”, “if (IPython.notebook.kernel != null) {n”, “ IPython.notebook.kernel.comm_manager.register_target(‘matplotlib’, mpl.mpl_figure_comm);n”, “}n”

], “text/plain”: [

“<IPython.core.display.Javascript object>”

]

}, “metadata”: {}, “output_type”: “display_data”

}, {

“data”: {
“text/html”: [

“<img src="data:image/png;base64,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" width="640">”

], “text/plain”: [

“<IPython.core.display.HTML object>”

]

}, “metadata”: {}, “output_type”: “display_data”

}

], “source”: [

“block = amp.blocks.Line(X, Y)n”, “n”, “plt.subplots_adjust(top=0.8) # squish the plot to make space for the controlsn”, “slider_ax = plt.axes([0.18, 0.89, 0.5, 0.03]) # the rect of the axisn”, “button_ax = plt.axes([0.78, 0.87, 0.1, 0.07]) # x, y, width, heightn”, “n”, “anim = amp.Animation([block])n”, “n”, “anim.toggle(ax=button_ax)n”, “anim.timeline_slider(text="TIME", ax=slider_ax, color="red", valfmt="%1.0f")n”, “# equivalent to:n”, “# anim.controls({‘text’:’TIME’, ‘ax’:slider_ax, ‘color’:’red’, ‘valfmt’:’%1.0f’},n”, “# {‘ax’:button_axis})n”, “n”, “anim.save_gif("images/controls")n”, “plt.show()”

]

}, {

“cell_type”: “raw”, “metadata”: {

“raw_mimetype”: “text/restructuredtext”

}, “source”: [

“.. image:: images/controls.gif”

]

}

], “metadata”: {

“celltoolbar”: “Raw Cell Format”, “kernelspec”: {

“display_name”: “Python 3”, “language”: “python”, “name”: “python3”

}, “language_info”: {

“codemirror_mode”: {

“name”: “ipython”, “version”: 3

}, “file_extension”: “.py”, “mimetype”: “text/x-python”, “name”: “python”, “nbconvert_exporter”: “python”, “pygments_lexer”: “ipython3”, “version”: “3.6.5”

}

}, “nbformat”: 4, “nbformat_minor”: 2

}