Created
January 19, 2018 15:35
-
-
Save ceptreee/3334d39c642f8c6f99ea373a85d6db45 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| "cells": [ | |
| { | |
| "cell_type": "code", | |
| "execution_count": 29, | |
| "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 images\n", | |
| " // almost always do), so we need to clear the canvas so that\n", | |
| " // 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_div\n", | |
| " 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 band\n", | |
| " // 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 updated\n", | |
| " // 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-buttons\n", | |
| " $( \".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 but\n", | |
| " * transferred with MIME type text/plain:\" errors on\n", | |
| " * Chrome. But how to set the MIME type? It doesn't seem\n", | |
| " * 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 takes\n", | |
| " // 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-canvas\n", | |
| "mpl.findpos = function(e) {\n", | |
| " //this section is from http://www.quirksmode.org/js/events_properties.html\n", | |
| " 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 bug\n", | |
| " targ = targ.parentNode;\n", | |
| "\n", | |
| " // jQuery normalizes the pageX and pageY\n", | |
| " // pageX,Y are the mouse positions relative to the document\n", | |
| " // offset() returns the position of the element relative to the document\n", | |
| " 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 keys\n", | |
| " * we need this to avoid circular references\n", | |
| " * http://stackoverflow.com/a/24161582/3208463\n", | |
| " */\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 to\n", | |
| " * the text insertion cursor when the button is pressed. We want\n", | |
| " * to control all of the cursor setting manually through the\n", | |
| " * '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 event\n", | |
| "}\n", | |
| "\n", | |
| "mpl.figure.prototype.key_event = function(event, name) {\n", | |
| "\n", | |
| " // Prevent repeat events\n", | |
| " if (name == 'key_press')\n", | |
| " {\n", | |
| " if (event.which === this._key)\n", | |
| " return;\n", | |
| " else\n", | |
| " 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 comm\n", | |
| " // object with the appropriate methods. Currently this is a non binary\n", | |
| " // 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 overriden (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 process\n", | |
| " // 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 Comm\n", | |
| " // 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 real\n", | |
| " // 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.ratio\n", | |
| " 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.ratio\n", | |
| " 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 so\n", | |
| " // 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 = this\n", | |
| " 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 'focusable\n", | |
| " el.attr('tabindex', 0)\n", | |
| " // reach out to IPython and tell the keyboard manager to turn it's self\n", | |
| " // off when our div gets focus\n", | |
| "\n", | |
| " // location in version 3\n", | |
| " if (IPython.notebook.keyboard_manager) {\n", | |
| " IPython.notebook.keyboard_manager.register_events(el);\n", | |
| " }\n", | |
| " else {\n", | |
| " // location in version 2\n", | |
| " 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+enter\n", | |
| " if (event.shiftKey && event.which == 13) {\n", | |
| " this.canvas_div.blur();\n", | |
| " event.shiftKey = false;\n", | |
| " // Send a \"J\" for go to next cell\n", | |
| " 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 for\n", | |
| " // 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 output\n", | |
| " 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" | |
| }, | |
| { | |
| "data": { | |
| "text/plain": [ | |
| "8" | |
| ] | |
| }, | |
| "execution_count": 29, | |
| "metadata": {}, | |
| "output_type": "execute_result" | |
| } | |
| ], | |
| "source": [ | |
| "%matplotlib notebook\n", | |
| "import numpy as np\n", | |
| "import matplotlib.pyplot as plt\n", | |
| "import matplotlib.animation as animation\n", | |
| "\n", | |
| "plt.rcParams[\"font.size\"] = 18\n", | |
| "\n", | |
| "θ_N = 100\n", | |
| "θlm = [0, 2*np.pi] \n", | |
| "θ = np.linspace(θlm[0], θlm[1], θ_N)\n", | |
| "\n", | |
| "x1 = np.cos(θ)\n", | |
| "x2 = np.sin(θ)\n", | |
| "x = np.vstack([x1,\n", | |
| " x2])\n", | |
| "\n", | |
| "# 行列\n", | |
| "A = np.array([ [2.0, 1],\n", | |
| " [1.0, 1.5] ])\n", | |
| "# Ax\n", | |
| "Ax = np.dot(A, x)\n", | |
| "\n", | |
| "lm = [-3, 3]\n", | |
| "c = ['k','C0']\n", | |
| "\n", | |
| "fig = plt.figure()\n", | |
| "# x\n", | |
| "plt.plot(x[0],x[1],color=c[0],linewidth=1,label='$x$')\n", | |
| "\n", | |
| "# Ax\n", | |
| "plt.plot(Ax[0],Ax[1],color=c[1],linewidth=1,label='$Ax$')\n", | |
| "\n", | |
| "i = 0\n", | |
| "# cx\n", | |
| "qvr_cx = plt.quiver(0,0, x[0][i], x[1][i],zorder=10, color=c[0], angles='xy', scale_units='xy', scale=1)\n", | |
| "\n", | |
| "# cAx\n", | |
| "qvr_cAx = plt.quiver(0,0,Ax[0][i],Ax[1][i],zorder=10, color=c[1], angles='xy', scale_units='xy', scale=1)\n", | |
| "\n", | |
| "plt.rcParams['text.usetex'] = True\n", | |
| "fs = 16\n", | |
| "txt1 = r'$A = \\left( \\begin{array}{ll} %.1f & %.1f \\\\ %.1f & %.1f \\end{array} \\right)$' % (A[0,0],A[0,1],A[1,0],A[1,1])\n", | |
| "plt.text(-2.8, 1.5, txt1,fontsize=fs)\n", | |
| "\n", | |
| "txt2= r'$||x||_2 = 1$'\n", | |
| "plt.text(-2.8, 2.5, txt2,fontsize=fs)\n", | |
| "\n", | |
| "plt.xlabel('$x_1$')\n", | |
| "plt.ylabel('$x_2$')\n", | |
| "plt.xlim(lm)\n", | |
| "plt.ylim(lm)\n", | |
| "plt.xticks(np.arange(lm[0],lm[1]+1))\n", | |
| "plt.yticks(np.arange(lm[0],lm[1]+1))\n", | |
| "plt.gca().set_aspect(1/plt.gca().get_data_ratio())\n", | |
| "plt.grid()\n", | |
| "plt.legend(loc=4)\n", | |
| "plt.tight_layout()\n", | |
| "\n", | |
| "def motion(e):\n", | |
| " x1= e.xdata\n", | |
| " x2 = e.ydata\n", | |
| " \n", | |
| " if (x1 is None) or (x2 is None):\n", | |
| " return\n", | |
| " \n", | |
| " r = np.sqrt(x1**2+x2**2)\n", | |
| " cx1 = x1 / r\n", | |
| " cx2 = x2 / r\n", | |
| " cx = np.array([ [cx1],\n", | |
| " [cx2] ])\n", | |
| " cAx = np.dot(A, cx)\n", | |
| " \n", | |
| " qvr_cx.set_UVC(cx[0], cx[1])\n", | |
| " qvr_cAx.set_UVC(cAx[0], cAx[1])\n", | |
| " plt.draw()\n", | |
| "\n", | |
| "fig.canvas.mpl_connect('motion_notify_event', motion)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [] | |
| } | |
| ], | |
| "metadata": { | |
| "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.3" | |
| } | |
| }, | |
| "nbformat": 4, | |
| "nbformat_minor": 2 | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment