olsndot/firmware/Spectrum Measurement.ipynb

7443 lines
681 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"import sqlite3\n",
"import time\n",
"from IPython import display\n",
"from datetime import datetime\n",
"import scipy.interpolate as inter\n",
"\n",
"import numpy as np\n",
"from matplotlib import pyplot as plt\n",
"%matplotlib notebook"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"db = sqlite3.connect('spectra.sqlite3')"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"def load_run(run_id):\n",
" data = db.execute('SELECT step, voltage, voltage_stdev FROM measurements WHERE run_id = ? AND led_on = 1 ORDER BY step ASC', (run_id,)).fetchall()\n",
" return zip(*data)"
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"def load_run_zero_cal(run_id, max_stdev=1e10):\n",
" data = db.execute('SELECT a.step, a.voltage, a.voltage_stdev, b.voltage, b.voltage_stdev '\n",
" 'FROM measurements a JOIN measurements b USING (step) '\n",
" 'WHERE a.run_id = ?1 AND a.led_on = 1 AND b.run_id = ?1 AND b.led_on = 0 '\n",
" 'AND a.voltage_stdev < ?2 AND b.voltage_stdev < ?2'\n",
" 'ORDER BY step ASC', (run_id, max_stdev)).fetchall()\n",
" steps, voltages, voltage_stdevs, zero_voltages, zero_stdevs = map(np.array, zip(*data))\n",
" return steps, voltages-zero_voltages, np.sqrt(np.square(voltage_stdevs) + np.square(zero_stdevs))"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"def plot_rgb(id_r, id_g, id_b, loader=load_run):\n",
" fig, ax = plt.subplots(1, 1)\n",
" fig.suptitle('Runs {}, {}, {} at {:%y-%m-%d %H:%M:%S}'.format(id_r, id_g, id_b, datetime.now()))\n",
" for run_id, color in [(id_g, 'green'), (id_r, 'red'), (id_b, 'blue')]:\n",
" steps, values, stdev = loader(run_id)\n",
" ax.errorbar(steps, values, yerr=stdev, color=color)\n",
" #ax.set_ylim([2.2, 5])\n",
" #plt.close(fig)\n",
" #return fig"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"application/javascript": [
"/* Put everything inside the global mpl namespace */\n",
"window.mpl = {};\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",
" 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",
" this.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 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);\n",
" canvas.attr('height', height);\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'];\n",
" var y0 = fig.canvas.height - msg['y0'];\n",
" var x1 = msg['x1'];\n",
" var y1 = fig.canvas.height - msg['y1'];\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;\n",
" var y = canvas_pos.y;\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",
" 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 + '\">');\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 dataURL = this.canvas.toDataURL();\n",
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\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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\">"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"plot_rgb(10, 9, 12)"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"def live_plot_rgb(id_r, id_g, id_b, interval=1, loader=load_run):\n",
" fig, ax = plt.subplots(1, 1)\n",
" fig.suptitle('Runs {}, {}, {} at {:%y-%m-%d %H:%M:%S}'.format(id_r, id_g, id_b, datetime.now()))\n",
" \n",
" while True:\n",
" ax.clear()\n",
" for run_id, color in [(id_g, 'green'), (id_r, 'red'), (id_b, 'blue')]:\n",
" steps, values, stdev = loader(run_id)\n",
" ax.errorbar(steps, values, yerr=stdev, color=color)\n",
" fig.canvas.draw()\n",
" time.sleep(1)"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"application/javascript": [
"/* Put everything inside the global mpl namespace */\n",
"window.mpl = {};\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",
" 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",
" this.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 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);\n",
" canvas.attr('height', height);\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'];\n",
" var y0 = fig.canvas.height - msg['y0'];\n",
" var x1 = msg['x1'];\n",
" var y1 = fig.canvas.height - msg['y1'];\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;\n",
" var y = canvas_pos.y;\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",
" 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 + '\">');\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 dataURL = this.canvas.toDataURL();\n",
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\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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AHOInm4blvr3NaItTmfEfkD7WbxvASwlOmr1T9ED1E8i8mQGZTID5VWnn5c9PN5da2M30SCV0WnhrU7Pk5L6ukxTRKfRuJC6XCcaXtP7WTJubTGDqPNr6Zp6/x0i8oVoS9tZ0ffmddFg50kd0VPEF0RbmPqL4+chIvJsaplPiQYyd7x5n5uKjug+JRqmtokGuIzEig4cMT/v9SJSNt39PUVPI59Pfcynoq2NmSkvIu+KvSVskthHAIt493k5e0Vct4Gr4vjFwd17lD70vyg6f6b48D/pudt/yqe+Tk+tpu62+Z9Fg3/6eRDPiQZsIiKibGGBBL8l5AbR/oxEREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREROStl0XkoIicEZETIvKeiNQIaYmIiIiIKKgqiUih1N9zicjTInJMRGJCViIiIiIiyjJ5ROQpEbkqIsVCXBYiIiIiCqJWInJaRFJE5IqIjAltcYiIiIgoqxQWkSdFpH2oC0JEREREWSdGdEBINQ/3lRWRgvzhD3/4wx/+8CeifsoK+/dTBnKJyEURecDNfWVFBPzhD3/4wx/+8Ccif8oKUapBIlIy9fcSIjJDRE6JSLybxxYUESQnJ+Ps2bP8CfFP//79Q14G/vCzCMcffh7h88PPIjx+kpOTzQBYMEuSBUWE9SLyh4icF5GjIrJGRGp5eGxBEcHZs2dBoZeUlBTqIlAqfhbhhZ9H+OBnER7Onj3LAEiWMACGEVas4YOfRXjh5xE++FmEBwZAsooBMIzYbLZQF4FS8bMIL/w8wgc/i/DAAEhWMQASERFFGAZAsooBkIiIKMIwAJJVDIBEREQRhgGQrGIAJCIiijAMgGQVAyARUbSw2YCkJGDQICAxUZdJSXo7RRUGQLKKAZCIKNqcPQuI6JKiEgMgWcUASEQUbRgAox4DIFnFABiheKaHiDxiAIx6DIBkFQNghGM9T0QuWDFEPQZAsooBMMKxniciF6wYoh4DIFnFABjhWM8TkQtWDFGPAZCsYgCMcKznicgFK4aoxwBIVjEARjjW80TkghVD1GMAJKsYACMc63kicsGKIeoxAJJVDIARjvU8Eblg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O2Ab3QB8F7FOedjboFba9d9h1+imNwLAzJwo4GkkclsA9nljF4A9sGtm/wN3c7y2hWTpbNg773kRt08FMDL3i3NaqQm7CQWwD6Jvwq5ligcwGsCUiPVrwD5BnpVbBTwNZBY6Yr332mdyRrQAeDnspt28AK6FfVLrknaftkXOuQr2F9SW6W57HsDnEeudCXsbXJR2/W8ArSLW6Q1gfg6U8XSR2bYA7P58hWDvMxfBDoTpf/RB20KypG/QJ4/8sDv0XgXVAOYW1QCePKIFwEgvAliS9re2Rc64HnbfsTYRt2dVA2gG3qjWyV/RtkVm7oLd/9XQtpCYMutD8wvUhya35Yc92rElgDuhPoC5IbPQkZ33XvuM/7IbAP8H4LN017Ut/HUb7MBxVSb3XQLgCDLvA5g/7fpCZAzfK6F+Zyciq22RmTthjxg2tC0kpidhDye/AEBB2KOPtkKj6HJaBwCl0v4uB+AN2CezQrBrmrYDeAl2E0st2CMdNQrYH2fAbla8GnboiE+7HofsvffaZ/yT1ba4EEB92AMM8qSt8xvsqS0MbQv/PAI7cDSPcn8cgNUAxsLeT86BPTI1/Sjg9lYoSckAAAFkSURBVLBrnlrA3m4PwZ6eRCNPj0+sbVEN9nts9pWmADYA6JtuHW0LyRYLwE7YcwV9DM2jlRvmwK6pOAj7hDUJQNV099eCPUr4EOxO8C/kdgFD7C7YzVb/pF3M35ek3Z+d996C9hk/ZLUtrgewDnYN0++ww8b9mTyHBW0LP6TCHuW7H+655dKHkIoA5qXd9yuAgTg2Ath4GHYoPwR74E6LnCx0SMXaFo1gh/EUAPsAfAvgadhflNLTthAREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREZFc8P8L+ylJX+++RQAAAABJRU5ErkJggg==\">"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"ename": "KeyboardInterrupt",
"evalue": "",
"output_type": "error",
"traceback": [
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[1;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)",
"\u001b[1;32m<ipython-input-18-5741f6ed4af4>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mlive_plot_rgb\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m14\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m15\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m13\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mloader\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mload_run_zero_cal\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[1;32m<ipython-input-16-f9d194801c7a>\u001b[0m in \u001b[0;36mlive_plot_rgb\u001b[1;34m(id_r, id_g, id_b, interval, loader)\u001b[0m\n\u001b[0;32m 9\u001b[0m \u001b[0max\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0merrorbar\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0msteps\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mvalues\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0myerr\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mstdev\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mcolor\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mcolor\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 10\u001b[0m \u001b[0mfig\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mcanvas\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mdraw\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 11\u001b[1;33m \u001b[0mtime\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msleep\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[1;31mKeyboardInterrupt\u001b[0m: "
]
}
],
"source": [
"#live_plot_rgb(14, 15, 13, loader=load_run_zero_cal)"
]
},
{
"cell_type": "code",
"execution_count": 72,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"def live_plot_rgb_splines(id_r, id_g, id_b, max_stdev=0.05, spline_s=1, interval=1, live=True):\n",
" fig, ax = plt.subplots(1, 1)\n",
" fig.suptitle('Runs {}, {}, {} at {:%y-%m-%d %H:%M:%S}'.format(id_r, id_g, id_b, datetime.now()))\n",
" \n",
" while True:\n",
" ax.clear()\n",
" colors = [\n",
" ((1,0,0), (1,0.8,0.8)),\n",
" ((0,1,0), (0.8,1,0.8)),\n",
" ((0,0,1), (0.8,0.8,1))\n",
" ]\n",
" for run_id, (color_dark, color_bright) in zip([id_r, id_g, id_b], colors):\n",
" steps, values, stdev = load_run_zero_cal(run_id, max_stdev)\n",
" ax.errorbar(steps, values, yerr=stdev, color=color_bright)\n",
" try:\n",
" spline = inter.UnivariateSpline(steps, values, s=spline_s)\n",
" ax.plot(steps, spline(steps), color=color_dark)\n",
" except:\n",
" pass\n",
" fig.canvas.draw()\n",
" if not live:\n",
" break\n",
" time.sleep(1)"
]
},
{
"cell_type": "code",
"execution_count": 40,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"application/javascript": [
"/* Put everything inside the global mpl namespace */\n",
"window.mpl = {};\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",
" 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",
" this.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 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);\n",
" canvas.attr('height', height);\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'];\n",
" var y0 = fig.canvas.height - msg['y0'];\n",
" var x1 = msg['x1'];\n",
" var y1 = fig.canvas.height - msg['y1'];\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;\n",
" var y = canvas_pos.y;\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",
" 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 + '\">');\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 dataURL = this.canvas.toDataURL();\n",
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\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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\">"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"live_plot_rgb_splines(14, 15, 13, live=False)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"* Go further than step 250 to capture some zeros beyond the red band to allow the spline fitter to do its job more properly\n",
"* Move the entire screen further down and further increase range to properly capture blue rolloff\n",
"* Decrease amplification to avoid clipping. Maybe change amplification midway for green channel. Currenlty set to 5GOhm using 10M transimp feedback R with 1:10 T feedback and ~1:50 gain voltage amp stage. Maybe go back to plain transimp amp with 10M gain, for a total gain of 500M\n",
"* Decrease VGND bias to allow for more headroom"
]
},
{
"cell_type": "code",
"execution_count": 96,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"application/javascript": [
"/* Put everything inside the global mpl namespace */\n",
"window.mpl = {};\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",
" 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",
" this.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 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);\n",
" canvas.attr('height', height);\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'];\n",
" var y0 = fig.canvas.height - msg['y0'];\n",
" var x1 = msg['x1'];\n",
" var y1 = fig.canvas.height - msg['y1'];\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;\n",
" var y = canvas_pos.y;\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",
" 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 + '\">');\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 dataURL = this.canvas.toDataURL();\n",
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\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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\">"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"live_plot_rgb_splines(42, 43, 40, spline_s=0.01, max_stdev=1.0, live=False)"
]
},
{
"cell_type": "code",
"execution_count": 104,
"metadata": {
"collapsed": false,
"scrolled": false
},
"outputs": [
{
"data": {
"application/javascript": [
"/* Put everything inside the global mpl namespace */\n",
"window.mpl = {};\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",
" 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",
" this.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 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);\n",
" canvas.attr('height', height);\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'];\n",
" var y0 = fig.canvas.height - msg['y0'];\n",
" var x1 = msg['x1'];\n",
" var y1 = fig.canvas.height - msg['y1'];\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;\n",
" var y = canvas_pos.y;\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",
" 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 + '\">');\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 dataURL = this.canvas.toDataURL();\n",
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\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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w0THbH4c4zVFNHx2EF225knR9x8ZvNuI9qRFDo2w42SfJ1qvyfpMEBERNflOWgbAbUXXWzPHJe0oImNFe8yWi64TuFSc9wDuJiKTRU//louO27IGgkTL+GfR2cZljWWaJ3p6sI1lm+tF5LeI+2KJ1gt2f+P9ZaKnG/tZHmsvGkpOdfg3RKIvA2Nycgr4PtFgWia6LuGt0jwAdhYdg7ZJdGzniVFeZ6hoOKlv/DFvm6F5W9FlVZaI7reVokMEurR4peZ6ivZAVjaW8+GIx/8nevp6i+j4xzHS/NiJ5jLR43Kr6CQP6ynRvUWDcKmEjzEnk0CWSfj9mz/fRWxjLjmzi9grFB1SEE3kPndSryNE5MsYr9mazwQREVHWe080MKTS2eJsUgARERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERFRFnhERH4XkVIRWS8iX4vIkXGes5OIjBGRzSJSIiLviUiXFJaRiIiIiJLoAAmHt7YicpeIrBWRbWI850sR+UZEdhaRXURkkoh8msIyEhEREVGKtBeRO0WkXkS6RtlmbxFpEJGelvuOaLxvz5SWjoiIiIiS5nzR07kNImKIyHMxtr1IRKps7q8WkX7JLxoRERERpdJOInKHiFwWY5trRGSNzf1rRWSAzf3biEh3EenMH/7whz/84Q9/Muqnu8QeEkZZZBvRCSGHR3n8IhHZanN/tB7A7iIC/vCHP/zhD3/4k5E/3YUCoa2IVIrIpVEe31t0jGDkGMB6sR8D2FlEsGLFCpSVlWXdz+DBgz0vA98b31tQ3lu2vz++t8z8ydb3tmLFCjMAdk5exCA/uV1Edm28/UcRGSW6tEu3GM/5XERyRSeK/EFEJorIhCjbdhYRlJWVIRvl5OR4XYSU4XvLTNn83oDsfn98b5kpW99bWVkZA2CW+1x0TF+FiKwSXc6ll+XxvRofO8ly304i8r7oqeLNIvKuRD9AGAAzFN9bZsrm9wZk9/vje8tM2freGADJrawOgLm5uV4XIWX43jJTNr83ILvfH99bZsrW98YASG5ldQAkIiLKRgyA5BYDIBERUYZhACS3GACJiIgyDAMgucUA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\">"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"live_plot_rgb_splines(45, 46, 44, spline_s=0.08, max_stdev=1.0, live=False)"
]
},
{
"cell_type": "code",
"execution_count": 169,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"def plot_rgb_foo(data_rgb, ids_rgb, spline_s=1):\n",
" fig, ax = plt.subplots(1, 1)\n",
" fig.suptitle('Runs {}(R), {}(G), {}(B) at {:%y-%m-%d %H:%M:%S}'.format(*ids_rgb, datetime.now()))\n",
"\n",
" colors = [\n",
" ((1,0,0), (1,0.8,0.8)),\n",
" ((0,1,0), (0.8,1,0.8)),\n",
" ((0,0,1), (0.8,0.8,1))\n",
" ]\n",
" for (steps, values, stdev), (color_dark, color_bright) in zip(data_rgb, colors):\n",
" ax.errorbar(steps, values, yerr=stdev, color=color_bright)\n",
" \n",
" spline = inter.UnivariateSpline(steps, values, s=spline_s)\n",
" ax.plot(steps, spline(steps), color=color_dark)"
]
},
{
"cell_type": "code",
"execution_count": 171,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Poly for run 45: 2\n",
"2.282e-06 x - 0.001576 x + 0.4019\n",
"Poly for run 46: 2\n",
"6.886e-07 x - 0.0005388 x + 0.1561\n",
"Poly for run 44: 2\n",
"1.258e-06 x - 0.001514 x + 0.5252\n"
]
},
{
"data": {
"application/javascript": [
"/* Put everything inside the global mpl namespace */\n",
"window.mpl = {};\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",
" 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",
" this.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 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);\n",
" canvas.attr('height', height);\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'];\n",
" var y0 = fig.canvas.height - msg['y0'];\n",
" var x1 = msg['x1'];\n",
" var y1 = fig.canvas.height - msg['y1'];\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;\n",
" var y = canvas_pos.y;\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",
" 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 + '\">');\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 dataURL = this.canvas.toDataURL();\n",
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\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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9I8tQ7/Q+zCHt2j1+oZone4M/f9L0T8CzSZL7WV1K+Gfp4a8fyIiyhDdJf6VQHpK/Uuuh4uOlUuFvqKNWbwOEu1h3Mf0WCvRwB7P+2+ohpR7oNTeKU5ERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERk4/9EZJWIFIvIVhH5n4gcH+U17UVkjIgUiUihiHwkIu2SWEYiIiIiSqAjpDa8NRGRB0Rks4jsFeE1k0Rkioh0EJF9ROQbEZmQxDISERERUZI0F5H7RaRaRDrabHOwiNSIyLGmx34feqxLUktHRERERAlzkejl3BoRCYrI8xG2HSAi5RaP7xaRSxJfNCIiIiJKpvYicp+IXBFhm7+IyCaLxzeLyJ8tHt9LRDqLSFt+8Ytf/OIXv/jlq6/OEnlIGKWRvURvCDnO5vkBIrLL4nG7HsDOIgJ+8Ytf/OIXv/jly6/OQhmhiYiUicjlNs8fLDpGMHwMYLVYjwFsKyJYt24dduzYkXZfWVlZrpeB743vLVPeW7q/P743f36l63tbt26dEQDbJi5ikJfcKyL7h77fT0RGik7t0inCayaKSI7ojSL7isjXIjLeZtu2IoIdO3YgHWVnZ7tdhKThe/OndH5vQHq/P743f0rX97Zjxw4GwDQ3UXRMX6mIbBCdzqWn6fmuoef6mh5rLyKjRS8VF4nIh2J/gjAA+hTfmz+l83sD0vv98b35U7q+NwZAciqtA2BOTo7bRUgavjd/Suf3BqT3++N786d0fW8MgORUWgdAIiKidMQASE4xABIREfkMAyA5xQBIRETkMwyA5BQDIBERkc8wAJJTDIBEREQ+wwBITjEAEhER+QwDIDnFAEhEROQzDIDkFAMgERGRzzAAklMMgERERD7DAEhOMQASERH5DAMgOcUASERE5DMMgOQUAyAREZHPMACSUwyAREREPsMASE4xABIREfkMAyA5xQBIRETkMwyA5BQDIBERkc8wAJJTDIBEREQ+wwBITjEAEhER+QwDIDnFAEhEROQzDIDkFAMgERGRzzAAklMMgERERD7DAEhOMQASERH5DAMgOcUASERE5DMMgOQUAyAREZHP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\">"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"ids = (45, 46, 44)\n",
"bands = [(260,410), (150,330), (100,260)]\n",
"poly_degree = 2\n",
"max_stdev = 1.0\n",
"remove_thresh = 0.05\n",
"\n",
"data_rgb = []\n",
"for run_id, (l, r) in zip(ids, bands):\n",
" steps, values, stdev = load_run_zero_cal(run_id, max_stdev)\n",
" \n",
" idxs = (np.abs(stdev[1:-1] - stdev[0:-2]) < remove_thresh) |\\\n",
" (np.abs(stdev[1:-1] - stdev[2:]) < remove_thresh)\n",
" idxs = np.hstack([np.array([True]), idxs, np.array([True])])\n",
" steps, values, stdev = steps[idxs], values[idxs], stdev[idxs]\n",
" \n",
" idxs = (steps < l) | (steps > r)\n",
" poly = np.poly1d(np.polyfit(steps[idxs], values[idxs], poly_degree))\n",
" print('Poly for run {}: {}'.format(run_id, str(poly).strip()))\n",
" \n",
" values -= poly(steps)\n",
" data_rgb.append((steps, values, stdev))\n",
"\n",
"plot_rgb_foo(data_rgb, ids, spline_s=0.05)"
]
},
{
"cell_type": "code",
"execution_count": 238,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"def plot_rgb_bar(data_rgb, ids_rgb, spline_s=1):\n",
" fig, ax = plt.subplots(1, 1)\n",
" fig.suptitle('Runs {}(R), {}(G), {}(B) at {:%y-%m-%d %H:%M:%S}'.format(*ids_rgb, datetime.now()))\n",
"\n",
" colors = [\n",
" ((1,0,0), (1,0.8,0.8)),\n",
" ((0,1,0), (0.8,1,0.8)),\n",
" ((0,0,1), (0.8,0.8,1))\n",
" ]\n",
" for (steps, values, stdev), (color_dark, color_bright) in zip(data_rgb, colors):\n",
" ax.errorbar(steps, values, yerr=stdev, color=color_bright)\n",
" \n",
" spline = inter.UnivariateSpline(steps, values, s=spline_s)\n",
" ax.plot(steps, spline(steps), color=color_dark)\n",
" \n",
" ax.set_xlim([380, 720])\n",
" ax.set_xlabel('$\\lambda [nm]$')\n",
" ax.set_ylabel('normalized amplitude')"
]
},
{
"cell_type": "code",
"execution_count": 226,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"application/javascript": [
"/* Put everything inside the global mpl namespace */\n",
"window.mpl = {};\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",
" 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",
" this.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 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);\n",
" canvas.attr('height', height);\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'];\n",
" var y0 = fig.canvas.height - msg['y0'];\n",
" var x1 = msg['x1'];\n",
" var y1 = fig.canvas.height - msg['y1'];\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;\n",
" var y = canvas_pos.y;\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",
" 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 + '\">');\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 dataURL = this.canvas.toDataURL();\n",
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\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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\">"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"(380, 720)"
]
},
"execution_count": 226,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"λ_sfh2701 = [ 300, 400, 500, 600, 700, 800, 900, 1000, 1100]\n",
"S_sfh2701 = [0.00, 0.20, 0.57, 0.76, 0.90, 1.00, 0.85, 0.37, 0.00]\n",
"Λ_sfh2701 = np.poly1d(np.polyfit(λ_sfh2701, S_sfh2701, 5))\n",
"r = np.arange(380, 720)\n",
"fig, ax = plt.subplots(1, 1)\n",
"ax.plot(r, Λ_sfh2701(r))\n",
"ax.set_xlim([380, 720])"
]
},
{
"cell_type": "code",
"execution_count": 257,
"metadata": {
"collapsed": false,
"scrolled": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Poly for run 45:\n",
" 2\n",
"2.282e-06 x - 0.001576 x + 0.4019\n",
"Poly for run 46:\n",
" 2\n",
"6.886e-07 x - 0.0005388 x + 0.1561\n",
"Poly for run 44:\n",
" 2\n",
"1.258e-06 x - 0.001514 x + 0.5252\n",
"[297, 228, 117] [339, 270, 210]\n",
"[330, 228, 159]\n"
]
},
{
"data": {
"application/javascript": [
"/* Put everything inside the global mpl namespace */\n",
"window.mpl = {};\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",
" 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",
" this.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 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);\n",
" canvas.attr('height', height);\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'];\n",
" var y0 = fig.canvas.height - msg['y0'];\n",
" var x1 = msg['x1'];\n",
" var y1 = fig.canvas.height - msg['y1'];\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;\n",
" var y = canvas_pos.y;\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",
" 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 + '\">');\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 dataURL = this.canvas.toDataURL();\n",
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\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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//1Sly7+sY+77ur37Z12klq18pcv3HCD/z55/XXp1VelggI/9uCCBWXvK8uXS7NmZX7wuWwZB5NHehGAyGST9wCuXl3yn+s///F3mE6Z4pfz8vxUmUMPlTbfXLrttspvM326v26o2L/+Jf3sZ76nccAA34PwyCP+MXGl5zJzpj/NVK+e/8EotnKlH6y2Wzdp662lefPKrm/KFKl/f38X44aaPVu66aaNexrr88+lk06Sbr5Z+v57X1ZYKD3zjL97snZtP5bak096TD/0kNSsme8l6d3b/zDWqiUdeKA0eLC/uH7BAo/qLbaQ+vThDx1y05w50qRJ0htvSH/9q4fe7bf7YWXatPE43H13f6Zh++39AWKjRv6Ap2FDv1x8+vnP/WPq9trLP+2mePl220m/+pV04YXS2WdLxx/vl7t3l3r18t9bl1wi9eghtW8vNW3qB7g+7DDp//7P53LiiX79CSf4IZV++1t/7fNvfuO36d7d3wDTu7ePdeGFftuOHX1OXbv6ui691K8//3y/7Smn+Nd17+4P5Irnc9VVfpujj5b23lvaf3+/zemn+9d16+Zz3Xlnv+7Xv/bbn3aaz7tNG/++deggHXusdPLJvs177OHfj5Yt/ffJMcf4PLt39yDv2NHnevzxvl1du/p6mjWTmjf3rz/oIKlzZ1/vHnv4z2jffX1OvXr596pLF9850Latz+23v5Wuv14691ypUyf/Hrdq5XM980z/uXTr5rffYQef/yGH+Peka1f/+3HAAT7nzp19vkcf7ef32Uf65S/9+9Spk3/NkUf6bVu39u9Dp07+PbjgAv9+77efz2H33X29F14o9etX8v1r397n0qaNb2PxOK1a+fJDD/VxTj3V57fPPiUPYIrnsb43PCaNAERlMr0G8Fur5DWAeXl5OuaYfG22Wb62375Axx3nd/7ST8++8II/PZvpqdY1azwW27f3CKrMK6/4naxYYaH/sh892j+Efvp0D7+dd5Yef7zkdr17+y+Qe+6RWrSQfvjBlw8Z4n8MVq4s+SVebOpU/wPSsaOvY9gwv92SJf406u9/7welLt7zVljolxs29D8+bdr43rdi8+f7L7n/+z//+jVr/GtGjPBtv+gi/wVcv77f7uijpW23lf78Z2nxYn9qfMcd/fqddvJP6yj9vZw1y78Pp55a8setWzf/ngBpsWSJ7zGfNMn/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\">"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/usr/lib64/python3.5/site-packages/matplotlib/pyplot.py:516: RuntimeWarning: More than 20 figures have been opened. Figures created through the pyplot interface (`matplotlib.pyplot.figure`) are retained until explicitly closed and may consume too much memory. (To control this warning, see the rcParam `figure.max_open_warning`).\n",
" max_open_warning, RuntimeWarning)\n"
]
},
{
"data": {
"application/javascript": [
"/* Put everything inside the global mpl namespace */\n",
"window.mpl = {};\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",
" 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",
" this.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 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);\n",
" canvas.attr('height', height);\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'];\n",
" var y0 = fig.canvas.height - msg['y0'];\n",
" var x1 = msg['x1'];\n",
" var y1 = fig.canvas.height - msg['y1'];\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;\n",
" var y = canvas_pos.y;\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",
" 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 + '\">');\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 dataURL = this.canvas.toDataURL();\n",
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\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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\">"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"ids = (45, 46, 44) # Run IDs of runs for R, G and B channel\n",
"\n",
"# Approximate bands of interest for R, G and B channelsfor offset and stray light correction.\n",
"bands = [(260,410), (150,330), (100,260)] # [step]\n",
"\n",
"# The wavelengths are from a random RGB LED datasheet and are just preliminary starting values.\n",
"# https://www.sparkfun.com/datasheets/Components/YSL-R596CR3G4B5C-C10.pdf\n",
"λ_led = [623, 518, 466] # [nm] Assumed wavelengths of R, G and B spectral peaks.\n",
"λ_be = 400 # [nm] Approximate short-λ edge of blue band\n",
"y_edge_min = 0.5\n",
"\n",
"poly_degree = 2 # degree of polynomial for stray light and offset correction. Should be 1 or 2.\n",
"\n",
"max_stdev = 1.0 # [V] Nerved value that has been used for outlier removal in earlier tries\n",
"\n",
"remove_thresh = 0.05 # [V] standard deviation delta threshold for outlier removal\n",
"\n",
"# ---\n",
"data_rgb = []\n",
"for run_id, (l, r) in zip(ids, bands):\n",
" # Load this channel from the database\n",
" steps, values, stdev = load_run_zero_cal(run_id, max_stdev)\n",
" \n",
" # Remove outlier values whose standard deviation is much larger than that of their right and left neighbors\n",
" idxs = (np.abs(stdev[1:-1] - stdev[0:-2]) < remove_thresh) |\\\n",
" (np.abs(stdev[1:-1] - stdev[2:]) < remove_thresh)\n",
" idxs = np.hstack([np.array([True]), idxs, np.array([True])])\n",
" steps, values, stdev = steps[idxs], values[idxs], stdev[idxs]\n",
" \n",
" # Remove offset and stray light by fitting a second-order polynomial over the parts of the curve\n",
" # that are clearly *not* part of the primary peak.\n",
" idxs = (steps < l) | (steps > r)\n",
" poly = np.poly1d(np.polyfit(steps[idxs], values[idxs], poly_degree))\n",
" print('Poly for run {}:'.format(run_id))\n",
" print(poly)\n",
" values -= poly(steps)\n",
" \n",
" data_rgb.append((steps, values, stdev))\n",
"\n",
"\n",
"# Calibrate wavelength axis using assumed peaks for r, g and b. Use least-squares polyfit for getting coefficients.\n",
"peaks = [ x[np.argmax(y)] for x, y, σ2 in data_rgb ]\n",
"edgesl = [ x[np.argmax(y > y_edge_min)] for x, y, σ2 in data_rgb ]\n",
"print(edgesl, peaks)\n",
"\n",
"Λ_est = np.poly1d(np.polyfit([edgesl[2], peaks[0]], [λ_be, λ_led[0]], 1))\n",
"\n",
"data_tmp = [ (x, Λ_est(x), y, σ2) for x, y, σ2 in data_rgb ]\n",
"data_tmp = [ (x, λ, y/Λ_sfh2701(λ), σ2) for x, λ, y, σ2 in data_tmp ]\n",
"# Limit wavelength range\n",
"data_tmp = [ (x[λ > 380], λ[λ > 380], y[λ > 380], σ2[λ > 380]) for x, λ, y, σ2 in data_tmp ]\n",
"peaks = [ x[np.argmax(y)] for x, λ, y, σ2 in data_tmp ]\n",
"Λ = np.poly1d(np.polyfit(peaks, λ_led, 1))\n",
"\n",
"data_rgb = [ (Λ(x), y, σ2) for x, y, σ2 in data_rgb ]\n",
"data_rgb = [ (λ, y/Λ_sfh2701(λ), σ2) for λ, y, σ2 in data_rgb ]\n",
"\n",
"# Limit wavelength range to slightly-larger-than visible range. We're getting improbably large values in the\n",
"# utraviolet region that are probably caused by stray light.\n",
"data_rgb = [ (λ[λ > 380], y[λ > 380], σ2[λ > 380]) for λ, y, σ2 in data_rgb ]\n",
"\n",
"# Normalize amplitude data to brightest channel for ease of reading\n",
"max_val = max(np.max(y) for λ, y, σ2 in data_rgb)\n",
"data_rgb = [ (λ, y/max_val, σ2/max_val) for λ, y, σ2 in data_rgb ]\n",
"\n",
"plot_rgb_bar(data_rgb, ids, spline_s=0.005)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
}
},
"nbformat": 4,
"nbformat_minor": 0
}