6925 lines
638 KiB
Text
6925 lines
638 KiB
Text
{
|
||
"cells": [
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 6,
|
||
"metadata": {
|
||
"collapsed": true
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"import sqlite3\n",
|
||
"import time\n",
|
||
"from IPython import display\n",
|
||
"from datetime import datetime\n",
|
||
"import scipy.interpolate as inter\n",
|
||
"from scipy import integrate\n",
|
||
"\n",
|
||
"import numpy as np\n",
|
||
"from matplotlib import pyplot as plt\n",
|
||
"%matplotlib notebook"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 7,
|
||
"metadata": {
|
||
"collapsed": true
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"db = sqlite3.connect('spectra.sqlite3')"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 8,
|
||
"metadata": {
|
||
"collapsed": true
|
||
},
|
||
"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": 9,
|
||
"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": 10,
|
||
"metadata": {
|
||
"collapsed": true
|
||
},
|
||
"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": 11,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"application/javascript": [
|
||
"/* Put everything inside the global mpl namespace */\n",
|
||
"window.mpl = {};\n",
|
||
"\n",
|
||
"\n",
|
||
"mpl.get_websocket_type = function() {\n",
|
||
" if (typeof(WebSocket) !== 'undefined') {\n",
|
||
" return WebSocket;\n",
|
||
" } else if (typeof(MozWebSocket) !== 'undefined') {\n",
|
||
" return MozWebSocket;\n",
|
||
" } else {\n",
|
||
" alert('Your browser does not have WebSocket support.' +\n",
|
||
" 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
|
||
" 'Firefox 4 and 5 are also supported but you ' +\n",
|
||
" 'have to enable WebSockets in about:config.');\n",
|
||
" };\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
|
||
" this.id = figure_id;\n",
|
||
"\n",
|
||
" this.ws = websocket;\n",
|
||
"\n",
|
||
" this.supports_binary = (this.ws.binaryType != undefined);\n",
|
||
"\n",
|
||
" if (!this.supports_binary) {\n",
|
||
" var warnings = document.getElementById(\"mpl-warnings\");\n",
|
||
" if (warnings) {\n",
|
||
" warnings.style.display = 'block';\n",
|
||
" warnings.textContent = (\n",
|
||
" \"This browser does not support binary websocket messages. \" +\n",
|
||
" \"Performance may be slow.\");\n",
|
||
" }\n",
|
||
" }\n",
|
||
"\n",
|
||
" this.imageObj = new Image();\n",
|
||
"\n",
|
||
" this.context = undefined;\n",
|
||
" this.message = undefined;\n",
|
||
" this.canvas = undefined;\n",
|
||
" this.rubberband_canvas = undefined;\n",
|
||
" this.rubberband_context = undefined;\n",
|
||
" this.format_dropdown = undefined;\n",
|
||
"\n",
|
||
" this.image_mode = 'full';\n",
|
||
"\n",
|
||
" this.root = $('<div/>');\n",
|
||
" this._root_extra_style(this.root)\n",
|
||
" this.root.attr('style', 'display: inline-block');\n",
|
||
"\n",
|
||
" $(parent_element).append(this.root);\n",
|
||
"\n",
|
||
" this._init_header(this);\n",
|
||
" this._init_canvas(this);\n",
|
||
" this._init_toolbar(this);\n",
|
||
"\n",
|
||
" var fig = this;\n",
|
||
"\n",
|
||
" this.waiting = false;\n",
|
||
"\n",
|
||
" this.ws.onopen = function () {\n",
|
||
" fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
|
||
" fig.send_message(\"send_image_mode\", {});\n",
|
||
" if (mpl.ratio != 1) {\n",
|
||
" fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
|
||
" }\n",
|
||
" fig.send_message(\"refresh\", {});\n",
|
||
" }\n",
|
||
"\n",
|
||
" this.imageObj.onload = function() {\n",
|
||
" if (fig.image_mode == 'full') {\n",
|
||
" // Full images could contain transparency (where diff images\n",
|
||
" // almost always do), so we need to clear the canvas so that\n",
|
||
" // there is no ghosting.\n",
|
||
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
||
" }\n",
|
||
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
||
" };\n",
|
||
"\n",
|
||
" this.imageObj.onunload = function() {\n",
|
||
" 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 backingStore = this.context.backingStorePixelRatio ||\n",
|
||
"\tthis.context.webkitBackingStorePixelRatio ||\n",
|
||
"\tthis.context.mozBackingStorePixelRatio ||\n",
|
||
"\tthis.context.msBackingStorePixelRatio ||\n",
|
||
"\tthis.context.oBackingStorePixelRatio ||\n",
|
||
"\tthis.context.backingStorePixelRatio || 1;\n",
|
||
"\n",
|
||
" mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
|
||
"\n",
|
||
" var rubberband = $('<canvas/>');\n",
|
||
" rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
|
||
"\n",
|
||
" var pass_mouse_events = true;\n",
|
||
"\n",
|
||
" canvas_div.resizable({\n",
|
||
" start: function(event, ui) {\n",
|
||
" pass_mouse_events = false;\n",
|
||
" },\n",
|
||
" resize: function(event, ui) {\n",
|
||
" fig.request_resize(ui.size.width, ui.size.height);\n",
|
||
" },\n",
|
||
" stop: function(event, ui) {\n",
|
||
" pass_mouse_events = true;\n",
|
||
" fig.request_resize(ui.size.width, ui.size.height);\n",
|
||
" },\n",
|
||
" });\n",
|
||
"\n",
|
||
" function mouse_event_fn(event) {\n",
|
||
" if (pass_mouse_events)\n",
|
||
" return fig.mouse_event(event, event['data']);\n",
|
||
" }\n",
|
||
"\n",
|
||
" rubberband.mousedown('button_press', mouse_event_fn);\n",
|
||
" rubberband.mouseup('button_release', mouse_event_fn);\n",
|
||
" // Throttle sequential mouse events to 1 every 20ms.\n",
|
||
" rubberband.mousemove('motion_notify', mouse_event_fn);\n",
|
||
"\n",
|
||
" rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
|
||
" rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
|
||
"\n",
|
||
" canvas_div.on(\"wheel\", function (event) {\n",
|
||
" event = event.originalEvent;\n",
|
||
" event['data'] = 'scroll'\n",
|
||
" if (event.deltaY < 0) {\n",
|
||
" event.step = 1;\n",
|
||
" } else {\n",
|
||
" event.step = -1;\n",
|
||
" }\n",
|
||
" mouse_event_fn(event);\n",
|
||
" });\n",
|
||
"\n",
|
||
" canvas_div.append(canvas);\n",
|
||
" canvas_div.append(rubberband);\n",
|
||
"\n",
|
||
" this.rubberband = rubberband;\n",
|
||
" this.rubberband_canvas = rubberband[0];\n",
|
||
" this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
|
||
" this.rubberband_context.strokeStyle = \"#000000\";\n",
|
||
"\n",
|
||
" this._resize_canvas = function(width, height) {\n",
|
||
" // Keep the size of the canvas, canvas container, and rubber band\n",
|
||
" // canvas in synch.\n",
|
||
" canvas_div.css('width', width)\n",
|
||
" canvas_div.css('height', height)\n",
|
||
"\n",
|
||
" canvas.attr('width', width * mpl.ratio);\n",
|
||
" canvas.attr('height', height * mpl.ratio);\n",
|
||
" canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
|
||
"\n",
|
||
" rubberband.attr('width', width);\n",
|
||
" rubberband.attr('height', height);\n",
|
||
" }\n",
|
||
"\n",
|
||
" // Set the figure to an initial 600x600px, this will subsequently be updated\n",
|
||
" // upon first draw.\n",
|
||
" this._resize_canvas(600, 600);\n",
|
||
"\n",
|
||
" // Disable right mouse context menu.\n",
|
||
" $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
|
||
" return false;\n",
|
||
" });\n",
|
||
"\n",
|
||
" function set_focus () {\n",
|
||
" canvas.focus();\n",
|
||
" canvas_div.focus();\n",
|
||
" }\n",
|
||
"\n",
|
||
" window.setTimeout(set_focus, 100);\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype._init_toolbar = function() {\n",
|
||
" var fig = this;\n",
|
||
"\n",
|
||
" var nav_element = $('<div/>')\n",
|
||
" nav_element.attr('style', 'width: 100%');\n",
|
||
" this.root.append(nav_element);\n",
|
||
"\n",
|
||
" // Define a callback function for later on.\n",
|
||
" function toolbar_event(event) {\n",
|
||
" return fig.toolbar_button_onclick(event['data']);\n",
|
||
" }\n",
|
||
" function toolbar_mouse_event(event) {\n",
|
||
" return fig.toolbar_button_onmouseover(event['data']);\n",
|
||
" }\n",
|
||
"\n",
|
||
" for(var toolbar_ind in mpl.toolbar_items) {\n",
|
||
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
|
||
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
|
||
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
|
||
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
|
||
"\n",
|
||
" if (!name) {\n",
|
||
" // put a spacer in here.\n",
|
||
" continue;\n",
|
||
" }\n",
|
||
" var button = $('<button/>');\n",
|
||
" button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
|
||
" 'ui-button-icon-only');\n",
|
||
" button.attr('role', 'button');\n",
|
||
" button.attr('aria-disabled', 'false');\n",
|
||
" button.click(method_name, toolbar_event);\n",
|
||
" button.mouseover(tooltip, toolbar_mouse_event);\n",
|
||
"\n",
|
||
" var icon_img = $('<span/>');\n",
|
||
" icon_img.addClass('ui-button-icon-primary ui-icon');\n",
|
||
" icon_img.addClass(image);\n",
|
||
" icon_img.addClass('ui-corner-all');\n",
|
||
"\n",
|
||
" var tooltip_span = $('<span/>');\n",
|
||
" tooltip_span.addClass('ui-button-text');\n",
|
||
" tooltip_span.html(tooltip);\n",
|
||
"\n",
|
||
" button.append(icon_img);\n",
|
||
" button.append(tooltip_span);\n",
|
||
"\n",
|
||
" nav_element.append(button);\n",
|
||
" }\n",
|
||
"\n",
|
||
" var fmt_picker_span = $('<span/>');\n",
|
||
"\n",
|
||
" var fmt_picker = $('<select/>');\n",
|
||
" fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
|
||
" fmt_picker_span.append(fmt_picker);\n",
|
||
" nav_element.append(fmt_picker_span);\n",
|
||
" this.format_dropdown = fmt_picker[0];\n",
|
||
"\n",
|
||
" for (var ind in mpl.extensions) {\n",
|
||
" var fmt = mpl.extensions[ind];\n",
|
||
" var option = $(\n",
|
||
" '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
|
||
" fmt_picker.append(option)\n",
|
||
" }\n",
|
||
"\n",
|
||
" // Add hover states to the ui-buttons\n",
|
||
" $( \".ui-button\" ).hover(\n",
|
||
" function() { $(this).addClass(\"ui-state-hover\");},\n",
|
||
" function() { $(this).removeClass(\"ui-state-hover\");}\n",
|
||
" );\n",
|
||
"\n",
|
||
" var status_bar = $('<span class=\"mpl-message\"/>');\n",
|
||
" nav_element.append(status_bar);\n",
|
||
" this.message = status_bar[0];\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
|
||
" // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
|
||
" // which will in turn request a refresh of the image.\n",
|
||
" this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.send_message = function(type, properties) {\n",
|
||
" properties['type'] = type;\n",
|
||
" properties['figure_id'] = this.id;\n",
|
||
" this.ws.send(JSON.stringify(properties));\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.send_draw_message = function() {\n",
|
||
" if (!this.waiting) {\n",
|
||
" this.waiting = true;\n",
|
||
" this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
|
||
" }\n",
|
||
"}\n",
|
||
"\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
|
||
" var format_dropdown = fig.format_dropdown;\n",
|
||
" var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
|
||
" fig.ondownload(fig, format);\n",
|
||
"}\n",
|
||
"\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
|
||
" var size = msg['size'];\n",
|
||
" if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
|
||
" fig._resize_canvas(size[0], size[1]);\n",
|
||
" fig.send_message(\"refresh\", {});\n",
|
||
" };\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
|
||
" var x0 = msg['x0'] / mpl.ratio;\n",
|
||
" var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
|
||
" var x1 = msg['x1'] / mpl.ratio;\n",
|
||
" var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
|
||
" x0 = Math.floor(x0) + 0.5;\n",
|
||
" y0 = Math.floor(y0) + 0.5;\n",
|
||
" x1 = Math.floor(x1) + 0.5;\n",
|
||
" y1 = Math.floor(y1) + 0.5;\n",
|
||
" var min_x = Math.min(x0, x1);\n",
|
||
" var min_y = Math.min(y0, y1);\n",
|
||
" var width = Math.abs(x1 - x0);\n",
|
||
" var height = Math.abs(y1 - y0);\n",
|
||
"\n",
|
||
" fig.rubberband_context.clearRect(\n",
|
||
" 0, 0, fig.canvas.width, fig.canvas.height);\n",
|
||
"\n",
|
||
" fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
|
||
" // Updates the figure title.\n",
|
||
" fig.header.textContent = msg['label'];\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
|
||
" var cursor = msg['cursor'];\n",
|
||
" switch(cursor)\n",
|
||
" {\n",
|
||
" case 0:\n",
|
||
" cursor = 'pointer';\n",
|
||
" break;\n",
|
||
" case 1:\n",
|
||
" cursor = 'default';\n",
|
||
" break;\n",
|
||
" case 2:\n",
|
||
" cursor = 'crosshair';\n",
|
||
" break;\n",
|
||
" case 3:\n",
|
||
" cursor = 'move';\n",
|
||
" break;\n",
|
||
" }\n",
|
||
" fig.rubberband_canvas.style.cursor = cursor;\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_message = function(fig, msg) {\n",
|
||
" fig.message.textContent = msg['message'];\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
|
||
" // Request the server to send over a new figure.\n",
|
||
" fig.send_draw_message();\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
|
||
" fig.image_mode = msg['mode'];\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.updated_canvas_event = function() {\n",
|
||
" // Called whenever the canvas gets updated.\n",
|
||
" this.send_message(\"ack\", {});\n",
|
||
"}\n",
|
||
"\n",
|
||
"// A function to construct a web socket function for onmessage handling.\n",
|
||
"// Called in the figure constructor.\n",
|
||
"mpl.figure.prototype._make_on_message_function = function(fig) {\n",
|
||
" return function socket_on_message(evt) {\n",
|
||
" if (evt.data instanceof Blob) {\n",
|
||
" /* FIXME: We get \"Resource interpreted as Image but\n",
|
||
" * transferred with MIME type text/plain:\" errors on\n",
|
||
" * Chrome. But how to set the MIME type? It doesn't seem\n",
|
||
" * to be part of the websocket stream */\n",
|
||
" evt.data.type = \"image/png\";\n",
|
||
"\n",
|
||
" /* Free the memory for the previous frames */\n",
|
||
" if (fig.imageObj.src) {\n",
|
||
" (window.URL || window.webkitURL).revokeObjectURL(\n",
|
||
" fig.imageObj.src);\n",
|
||
" }\n",
|
||
"\n",
|
||
" fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
|
||
" evt.data);\n",
|
||
" fig.updated_canvas_event();\n",
|
||
" fig.waiting = false;\n",
|
||
" return;\n",
|
||
" }\n",
|
||
" else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
|
||
" fig.imageObj.src = evt.data;\n",
|
||
" fig.updated_canvas_event();\n",
|
||
" fig.waiting = false;\n",
|
||
" return;\n",
|
||
" }\n",
|
||
"\n",
|
||
" var msg = JSON.parse(evt.data);\n",
|
||
" var msg_type = msg['type'];\n",
|
||
"\n",
|
||
" // Call the \"handle_{type}\" callback, which takes\n",
|
||
" // the figure and JSON message as its only arguments.\n",
|
||
" try {\n",
|
||
" var callback = fig[\"handle_\" + msg_type];\n",
|
||
" } catch (e) {\n",
|
||
" console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
|
||
" return;\n",
|
||
" }\n",
|
||
"\n",
|
||
" if (callback) {\n",
|
||
" try {\n",
|
||
" // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
|
||
" callback(fig, msg);\n",
|
||
" } catch (e) {\n",
|
||
" console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
|
||
" }\n",
|
||
" }\n",
|
||
" };\n",
|
||
"}\n",
|
||
"\n",
|
||
"// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
|
||
"mpl.findpos = function(e) {\n",
|
||
" //this section is from http://www.quirksmode.org/js/events_properties.html\n",
|
||
" var targ;\n",
|
||
" if (!e)\n",
|
||
" e = window.event;\n",
|
||
" if (e.target)\n",
|
||
" targ = e.target;\n",
|
||
" else if (e.srcElement)\n",
|
||
" targ = e.srcElement;\n",
|
||
" if (targ.nodeType == 3) // defeat Safari bug\n",
|
||
" targ = targ.parentNode;\n",
|
||
"\n",
|
||
" // jQuery normalizes the pageX and pageY\n",
|
||
" // pageX,Y are the mouse positions relative to the document\n",
|
||
" // offset() returns the position of the element relative to the document\n",
|
||
" var x = e.pageX - $(targ).offset().left;\n",
|
||
" var y = e.pageY - $(targ).offset().top;\n",
|
||
"\n",
|
||
" return {\"x\": x, \"y\": y};\n",
|
||
"};\n",
|
||
"\n",
|
||
"/*\n",
|
||
" * return a copy of an object with only non-object keys\n",
|
||
" * we need this to avoid circular references\n",
|
||
" * http://stackoverflow.com/a/24161582/3208463\n",
|
||
" */\n",
|
||
"function simpleKeys (original) {\n",
|
||
" return Object.keys(original).reduce(function (obj, key) {\n",
|
||
" if (typeof original[key] !== 'object')\n",
|
||
" obj[key] = original[key]\n",
|
||
" return obj;\n",
|
||
" }, {});\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.mouse_event = function(event, name) {\n",
|
||
" var canvas_pos = mpl.findpos(event)\n",
|
||
"\n",
|
||
" if (name === 'button_press')\n",
|
||
" {\n",
|
||
" this.canvas.focus();\n",
|
||
" this.canvas_div.focus();\n",
|
||
" }\n",
|
||
"\n",
|
||
" var x = canvas_pos.x * mpl.ratio;\n",
|
||
" var y = canvas_pos.y * mpl.ratio;\n",
|
||
"\n",
|
||
" this.send_message(name, {x: x, y: y, button: event.button,\n",
|
||
" step: event.step,\n",
|
||
" guiEvent: simpleKeys(event)});\n",
|
||
"\n",
|
||
" /* This prevents the web browser from automatically changing to\n",
|
||
" * the text insertion cursor when the button is pressed. We want\n",
|
||
" * to control all of the cursor setting manually through the\n",
|
||
" * 'cursor' event from matplotlib */\n",
|
||
" event.preventDefault();\n",
|
||
" return false;\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
|
||
" // Handle any extra behaviour associated with a key event\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.key_event = function(event, name) {\n",
|
||
"\n",
|
||
" // Prevent repeat events\n",
|
||
" if (name == 'key_press')\n",
|
||
" {\n",
|
||
" if (event.which === this._key)\n",
|
||
" return;\n",
|
||
" else\n",
|
||
" this._key = event.which;\n",
|
||
" }\n",
|
||
" if (name == 'key_release')\n",
|
||
" this._key = null;\n",
|
||
"\n",
|
||
" var value = '';\n",
|
||
" if (event.ctrlKey && event.which != 17)\n",
|
||
" value += \"ctrl+\";\n",
|
||
" if (event.altKey && event.which != 18)\n",
|
||
" value += \"alt+\";\n",
|
||
" if (event.shiftKey && event.which != 16)\n",
|
||
" value += \"shift+\";\n",
|
||
"\n",
|
||
" value += 'k';\n",
|
||
" value += event.which.toString();\n",
|
||
"\n",
|
||
" this._key_event_extra(event, name);\n",
|
||
"\n",
|
||
" this.send_message(name, {key: value,\n",
|
||
" guiEvent: simpleKeys(event)});\n",
|
||
" return false;\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
|
||
" if (name == 'download') {\n",
|
||
" this.handle_save(this, null);\n",
|
||
" } else {\n",
|
||
" this.send_message(\"toolbar_button\", {name: name});\n",
|
||
" }\n",
|
||
"};\n",
|
||
"\n",
|
||
"mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
|
||
" this.message.textContent = tooltip;\n",
|
||
"};\n",
|
||
"mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
|
||
"\n",
|
||
"mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
|
||
"\n",
|
||
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
|
||
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
||
" // object with the appropriate methods. Currently this is a non binary\n",
|
||
" // socket, so there is still some room for performance tuning.\n",
|
||
" var ws = {};\n",
|
||
"\n",
|
||
" ws.close = function() {\n",
|
||
" comm.close()\n",
|
||
" };\n",
|
||
" ws.send = function(m) {\n",
|
||
" //console.log('sending', m);\n",
|
||
" comm.send(m);\n",
|
||
" };\n",
|
||
" // Register the callback with on_msg.\n",
|
||
" comm.on_msg(function(msg) {\n",
|
||
" //console.log('receiving', msg['content']['data'], msg);\n",
|
||
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
|
||
" ws.onmessage(msg['content']['data'])\n",
|
||
" });\n",
|
||
" return ws;\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.mpl_figure_comm = function(comm, msg) {\n",
|
||
" // This is the function which gets called when the mpl process\n",
|
||
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
||
"\n",
|
||
" var id = msg.content.data.id;\n",
|
||
" // Get hold of the div created by the display call when the Comm\n",
|
||
" // socket was opened in Python.\n",
|
||
" var element = $(\"#\" + id);\n",
|
||
" var ws_proxy = comm_websocket_adapter(comm)\n",
|
||
"\n",
|
||
" function ondownload(figure, format) {\n",
|
||
" window.open(figure.imageObj.src);\n",
|
||
" }\n",
|
||
"\n",
|
||
" var fig = new mpl.figure(id, ws_proxy,\n",
|
||
" ondownload,\n",
|
||
" element.get(0));\n",
|
||
"\n",
|
||
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
||
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
||
" ws_proxy.onopen();\n",
|
||
"\n",
|
||
" fig.parent_element = element.get(0);\n",
|
||
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
||
" if (!fig.cell_info) {\n",
|
||
" console.error(\"Failed to find cell for figure\", id, fig);\n",
|
||
" return;\n",
|
||
" }\n",
|
||
"\n",
|
||
" var output_index = fig.cell_info[2]\n",
|
||
" var cell = fig.cell_info[0];\n",
|
||
"\n",
|
||
"};\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
|
||
" var width = fig.canvas.width/mpl.ratio\n",
|
||
" fig.root.unbind('remove')\n",
|
||
"\n",
|
||
" // Update the output cell to use the data from the current canvas.\n",
|
||
" fig.push_to_output();\n",
|
||
" var dataURL = fig.canvas.toDataURL();\n",
|
||
" // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
|
||
" // the notebook keyboard shortcuts fail.\n",
|
||
" IPython.keyboard_manager.enable()\n",
|
||
" $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
|
||
" fig.close_ws(fig, msg);\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.close_ws = function(fig, msg){\n",
|
||
" fig.send_message('closing', msg);\n",
|
||
" // fig.ws.close()\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
|
||
" // Turn the data on the canvas into data in the output cell.\n",
|
||
" var width = this.canvas.width/mpl.ratio\n",
|
||
" var dataURL = this.canvas.toDataURL();\n",
|
||
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.updated_canvas_event = function() {\n",
|
||
" // Tell IPython that the notebook contents must change.\n",
|
||
" IPython.notebook.set_dirty(true);\n",
|
||
" this.send_message(\"ack\", {});\n",
|
||
" var fig = this;\n",
|
||
" // Wait a second, then push the new image to the DOM so\n",
|
||
" // that it is saved nicely (might be nice to debounce this).\n",
|
||
" setTimeout(function () { fig.push_to_output() }, 1000);\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype._init_toolbar = function() {\n",
|
||
" var fig = this;\n",
|
||
"\n",
|
||
" var nav_element = $('<div/>')\n",
|
||
" nav_element.attr('style', 'width: 100%');\n",
|
||
" this.root.append(nav_element);\n",
|
||
"\n",
|
||
" // Define a callback function for later on.\n",
|
||
" function toolbar_event(event) {\n",
|
||
" return fig.toolbar_button_onclick(event['data']);\n",
|
||
" }\n",
|
||
" function toolbar_mouse_event(event) {\n",
|
||
" return fig.toolbar_button_onmouseover(event['data']);\n",
|
||
" }\n",
|
||
"\n",
|
||
" for(var toolbar_ind in mpl.toolbar_items){\n",
|
||
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
|
||
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
|
||
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
|
||
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
|
||
"\n",
|
||
" if (!name) { continue; };\n",
|
||
"\n",
|
||
" var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
|
||
" button.click(method_name, toolbar_event);\n",
|
||
" button.mouseover(tooltip, toolbar_mouse_event);\n",
|
||
" nav_element.append(button);\n",
|
||
" }\n",
|
||
"\n",
|
||
" // Add the status bar.\n",
|
||
" var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
|
||
" nav_element.append(status_bar);\n",
|
||
" this.message = status_bar[0];\n",
|
||
"\n",
|
||
" // Add the close button to the window.\n",
|
||
" var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
|
||
" var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
|
||
" button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
|
||
" button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
|
||
" buttongrp.append(button);\n",
|
||
" var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
|
||
" titlebar.prepend(buttongrp);\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype._root_extra_style = function(el){\n",
|
||
" var fig = this\n",
|
||
" el.on(\"remove\", function(){\n",
|
||
"\tfig.close_ws(fig, {});\n",
|
||
" });\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype._canvas_extra_style = function(el){\n",
|
||
" // this is important to make the div 'focusable\n",
|
||
" el.attr('tabindex', 0)\n",
|
||
" // reach out to IPython and tell the keyboard manager to turn it's self\n",
|
||
" // off when our div gets focus\n",
|
||
"\n",
|
||
" // location in version 3\n",
|
||
" if (IPython.notebook.keyboard_manager) {\n",
|
||
" IPython.notebook.keyboard_manager.register_events(el);\n",
|
||
" }\n",
|
||
" else {\n",
|
||
" // location in version 2\n",
|
||
" IPython.keyboard_manager.register_events(el);\n",
|
||
" }\n",
|
||
"\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
|
||
" var manager = IPython.notebook.keyboard_manager;\n",
|
||
" if (!manager)\n",
|
||
" manager = IPython.keyboard_manager;\n",
|
||
"\n",
|
||
" // Check for shift+enter\n",
|
||
" if (event.shiftKey && event.which == 13) {\n",
|
||
" this.canvas_div.blur();\n",
|
||
" // select the cell after this one\n",
|
||
" var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
|
||
" IPython.notebook.select(index + 1);\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": [
|
||
"<div id='11514acd-640e-40b2-8fef-5a43de1821e4'></div>"
|
||
],
|
||
"text/plain": [
|
||
"<IPython.core.display.HTML object>"
|
||
]
|
||
},
|
||
"metadata": {},
|
||
"output_type": "display_data"
|
||
},
|
||
{
|
||
"ename": "OperationalError",
|
||
"evalue": "no such column: run_id",
|
||
"output_type": "error",
|
||
"traceback": [
|
||
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
|
||
"\u001b[0;31mOperationalError\u001b[0m Traceback (most recent call last)",
|
||
"\u001b[0;32m<ipython-input-11-e90842d7a10f>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mplot_rgb\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m10\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m9\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m12\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
|
||
"\u001b[0;32m<ipython-input-10-e7656890afb7>\u001b[0m in \u001b[0;36mplot_rgb\u001b[0;34m(id_r, id_g, id_b, loader)\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0mfig\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msuptitle\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Runs {}, {}, {} at {:%y-%m-%d %H:%M:%S}'\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mformat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mid_r\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mid_g\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mid_b\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdatetime\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnow\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mrun_id\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcolor\u001b[0m \u001b[0;32min\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mid_g\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'green'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mid_r\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'red'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mid_b\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'blue'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 5\u001b[0;31m \u001b[0msteps\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mvalues\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mstdev\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mloader\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mrun_id\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 6\u001b[0m \u001b[0max\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0merrorbar\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msteps\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mvalues\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0myerr\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mstdev\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcolor\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mcolor\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 7\u001b[0m \u001b[0;31m#ax.set_ylim([2.2, 5])\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
|
||
"\u001b[0;32m<ipython-input-8-30216012fb53>\u001b[0m in \u001b[0;36mload_run\u001b[0;34m(run_id)\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mload_run\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mrun_id\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mdata\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mdb\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mexecute\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'SELECT step, voltage, voltage_stdev FROM measurements WHERE run_id = ? AND led_on = 1 ORDER BY step ASC'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mrun_id\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfetchall\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 3\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mzip\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
|
||
"\u001b[0;31mOperationalError\u001b[0m: no such column: run_id"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"plot_rgb(10, 9, 12)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": true
|
||
},
|
||
"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": null,
|
||
"metadata": {
|
||
"collapsed": true
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"#live_plot_rgb(14, 15, 13, loader=load_run_zero_cal)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 116,
|
||
"metadata": {
|
||
"collapsed": true
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"def live_plot_rgb_splines(id_r, id_g, id_b, id_w=None,\n",
|
||
" max_stdev=0.05, spline_s=1, interval=1,\n",
|
||
" live=True, show_title=True, save_svg=None):\n",
|
||
" fig, ax = plt.subplots(1, 1)\n",
|
||
" if show_title:\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,0,0.2)),\n",
|
||
" # ((0,1,0), (0,1,0,0.2)),\n",
|
||
" # ((0,0,1), (0,0,1,0.2)),\n",
|
||
" # ((0,0,0), (0,0,0,0.2))\n",
|
||
" #]\n",
|
||
" colors = [\n",
|
||
" (('#fe3ea0', '#ffd2e9')) #ff99cc\n",
|
||
" ]*4\n",
|
||
" runs = [id_r, id_g, id_b] if id_w is None else [id_r, id_g, id_b, id_w]\n",
|
||
" for run_id, (color_dark, color_bright) in zip(runs, colors):\n",
|
||
" steps, values, stdev = load_run_zero_cal(run_id, max_stdev)\n",
|
||
" ax.errorbar(steps, values, yerr=stdev, color=color_bright, zorder=1)\n",
|
||
" ax.spines['top'].set_visible(False)\n",
|
||
" ax.spines['right'].set_visible(False)\n",
|
||
" ax.spines['bottom'].set_color('#08bdf9')\n",
|
||
" ax.spines['left'].set_color('#08bdf9')\n",
|
||
" ax.tick_params(axis='x', colors='#01769D')\n",
|
||
" ax.tick_params(axis='y', colors='#01769D')\n",
|
||
" ax.xaxis.label.set_color('#01769D')\n",
|
||
" ax.yaxis.label.set_color('#01769D')\n",
|
||
" ax.set_xlabel('x [steps]')\n",
|
||
" ax.set_ylabel('Vpd [V]')\n",
|
||
" ax.grid(color='#08bdf9', linestyle=':')\n",
|
||
" try:\n",
|
||
" spline = inter.UnivariateSpline(steps, values, s=spline_s)\n",
|
||
" ax.plot(steps, spline(steps), color=color_dark, zorder=2)\n",
|
||
" except:\n",
|
||
" pass\n",
|
||
" fig.canvas.draw()\n",
|
||
" if save_svg:\n",
|
||
" fig.savefig(save_svg)\n",
|
||
" if save_svg or not live:\n",
|
||
" break\n",
|
||
" time.sleep(1)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 117,
|
||
"metadata": {
|
||
"scrolled": false
|
||
},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"application/javascript": [
|
||
"/* Put everything inside the global mpl namespace */\n",
|
||
"window.mpl = {};\n",
|
||
"\n",
|
||
"\n",
|
||
"mpl.get_websocket_type = function() {\n",
|
||
" if (typeof(WebSocket) !== 'undefined') {\n",
|
||
" return WebSocket;\n",
|
||
" } else if (typeof(MozWebSocket) !== 'undefined') {\n",
|
||
" return MozWebSocket;\n",
|
||
" } else {\n",
|
||
" alert('Your browser does not have WebSocket support.' +\n",
|
||
" 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
|
||
" 'Firefox 4 and 5 are also supported but you ' +\n",
|
||
" 'have to enable WebSockets in about:config.');\n",
|
||
" };\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
|
||
" this.id = figure_id;\n",
|
||
"\n",
|
||
" this.ws = websocket;\n",
|
||
"\n",
|
||
" this.supports_binary = (this.ws.binaryType != undefined);\n",
|
||
"\n",
|
||
" if (!this.supports_binary) {\n",
|
||
" var warnings = document.getElementById(\"mpl-warnings\");\n",
|
||
" if (warnings) {\n",
|
||
" warnings.style.display = 'block';\n",
|
||
" warnings.textContent = (\n",
|
||
" \"This browser does not support binary websocket messages. \" +\n",
|
||
" \"Performance may be slow.\");\n",
|
||
" }\n",
|
||
" }\n",
|
||
"\n",
|
||
" this.imageObj = new Image();\n",
|
||
"\n",
|
||
" this.context = undefined;\n",
|
||
" this.message = undefined;\n",
|
||
" this.canvas = undefined;\n",
|
||
" this.rubberband_canvas = undefined;\n",
|
||
" this.rubberband_context = undefined;\n",
|
||
" this.format_dropdown = undefined;\n",
|
||
"\n",
|
||
" this.image_mode = 'full';\n",
|
||
"\n",
|
||
" this.root = $('<div/>');\n",
|
||
" this._root_extra_style(this.root)\n",
|
||
" this.root.attr('style', 'display: inline-block');\n",
|
||
"\n",
|
||
" $(parent_element).append(this.root);\n",
|
||
"\n",
|
||
" this._init_header(this);\n",
|
||
" this._init_canvas(this);\n",
|
||
" this._init_toolbar(this);\n",
|
||
"\n",
|
||
" var fig = this;\n",
|
||
"\n",
|
||
" this.waiting = false;\n",
|
||
"\n",
|
||
" this.ws.onopen = function () {\n",
|
||
" fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
|
||
" fig.send_message(\"send_image_mode\", {});\n",
|
||
" if (mpl.ratio != 1) {\n",
|
||
" fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
|
||
" }\n",
|
||
" fig.send_message(\"refresh\", {});\n",
|
||
" }\n",
|
||
"\n",
|
||
" this.imageObj.onload = function() {\n",
|
||
" if (fig.image_mode == 'full') {\n",
|
||
" // Full images could contain transparency (where diff images\n",
|
||
" // almost always do), so we need to clear the canvas so that\n",
|
||
" // there is no ghosting.\n",
|
||
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
||
" }\n",
|
||
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
||
" };\n",
|
||
"\n",
|
||
" this.imageObj.onunload = function() {\n",
|
||
" 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 backingStore = this.context.backingStorePixelRatio ||\n",
|
||
"\tthis.context.webkitBackingStorePixelRatio ||\n",
|
||
"\tthis.context.mozBackingStorePixelRatio ||\n",
|
||
"\tthis.context.msBackingStorePixelRatio ||\n",
|
||
"\tthis.context.oBackingStorePixelRatio ||\n",
|
||
"\tthis.context.backingStorePixelRatio || 1;\n",
|
||
"\n",
|
||
" mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
|
||
"\n",
|
||
" var rubberband = $('<canvas/>');\n",
|
||
" rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
|
||
"\n",
|
||
" var pass_mouse_events = true;\n",
|
||
"\n",
|
||
" canvas_div.resizable({\n",
|
||
" start: function(event, ui) {\n",
|
||
" pass_mouse_events = false;\n",
|
||
" },\n",
|
||
" resize: function(event, ui) {\n",
|
||
" fig.request_resize(ui.size.width, ui.size.height);\n",
|
||
" },\n",
|
||
" stop: function(event, ui) {\n",
|
||
" pass_mouse_events = true;\n",
|
||
" fig.request_resize(ui.size.width, ui.size.height);\n",
|
||
" },\n",
|
||
" });\n",
|
||
"\n",
|
||
" function mouse_event_fn(event) {\n",
|
||
" if (pass_mouse_events)\n",
|
||
" return fig.mouse_event(event, event['data']);\n",
|
||
" }\n",
|
||
"\n",
|
||
" rubberband.mousedown('button_press', mouse_event_fn);\n",
|
||
" rubberband.mouseup('button_release', mouse_event_fn);\n",
|
||
" // Throttle sequential mouse events to 1 every 20ms.\n",
|
||
" rubberband.mousemove('motion_notify', mouse_event_fn);\n",
|
||
"\n",
|
||
" rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
|
||
" rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
|
||
"\n",
|
||
" canvas_div.on(\"wheel\", function (event) {\n",
|
||
" event = event.originalEvent;\n",
|
||
" event['data'] = 'scroll'\n",
|
||
" if (event.deltaY < 0) {\n",
|
||
" event.step = 1;\n",
|
||
" } else {\n",
|
||
" event.step = -1;\n",
|
||
" }\n",
|
||
" mouse_event_fn(event);\n",
|
||
" });\n",
|
||
"\n",
|
||
" canvas_div.append(canvas);\n",
|
||
" canvas_div.append(rubberband);\n",
|
||
"\n",
|
||
" this.rubberband = rubberband;\n",
|
||
" this.rubberband_canvas = rubberband[0];\n",
|
||
" this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
|
||
" this.rubberband_context.strokeStyle = \"#000000\";\n",
|
||
"\n",
|
||
" this._resize_canvas = function(width, height) {\n",
|
||
" // Keep the size of the canvas, canvas container, and rubber band\n",
|
||
" // canvas in synch.\n",
|
||
" canvas_div.css('width', width)\n",
|
||
" canvas_div.css('height', height)\n",
|
||
"\n",
|
||
" canvas.attr('width', width * mpl.ratio);\n",
|
||
" canvas.attr('height', height * mpl.ratio);\n",
|
||
" canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
|
||
"\n",
|
||
" rubberband.attr('width', width);\n",
|
||
" rubberband.attr('height', height);\n",
|
||
" }\n",
|
||
"\n",
|
||
" // Set the figure to an initial 600x600px, this will subsequently be updated\n",
|
||
" // upon first draw.\n",
|
||
" this._resize_canvas(600, 600);\n",
|
||
"\n",
|
||
" // Disable right mouse context menu.\n",
|
||
" $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
|
||
" return false;\n",
|
||
" });\n",
|
||
"\n",
|
||
" function set_focus () {\n",
|
||
" canvas.focus();\n",
|
||
" canvas_div.focus();\n",
|
||
" }\n",
|
||
"\n",
|
||
" window.setTimeout(set_focus, 100);\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype._init_toolbar = function() {\n",
|
||
" var fig = this;\n",
|
||
"\n",
|
||
" var nav_element = $('<div/>')\n",
|
||
" nav_element.attr('style', 'width: 100%');\n",
|
||
" this.root.append(nav_element);\n",
|
||
"\n",
|
||
" // Define a callback function for later on.\n",
|
||
" function toolbar_event(event) {\n",
|
||
" return fig.toolbar_button_onclick(event['data']);\n",
|
||
" }\n",
|
||
" function toolbar_mouse_event(event) {\n",
|
||
" return fig.toolbar_button_onmouseover(event['data']);\n",
|
||
" }\n",
|
||
"\n",
|
||
" for(var toolbar_ind in mpl.toolbar_items) {\n",
|
||
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
|
||
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
|
||
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
|
||
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
|
||
"\n",
|
||
" if (!name) {\n",
|
||
" // put a spacer in here.\n",
|
||
" continue;\n",
|
||
" }\n",
|
||
" var button = $('<button/>');\n",
|
||
" button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
|
||
" 'ui-button-icon-only');\n",
|
||
" button.attr('role', 'button');\n",
|
||
" button.attr('aria-disabled', 'false');\n",
|
||
" button.click(method_name, toolbar_event);\n",
|
||
" button.mouseover(tooltip, toolbar_mouse_event);\n",
|
||
"\n",
|
||
" var icon_img = $('<span/>');\n",
|
||
" icon_img.addClass('ui-button-icon-primary ui-icon');\n",
|
||
" icon_img.addClass(image);\n",
|
||
" icon_img.addClass('ui-corner-all');\n",
|
||
"\n",
|
||
" var tooltip_span = $('<span/>');\n",
|
||
" tooltip_span.addClass('ui-button-text');\n",
|
||
" tooltip_span.html(tooltip);\n",
|
||
"\n",
|
||
" button.append(icon_img);\n",
|
||
" button.append(tooltip_span);\n",
|
||
"\n",
|
||
" nav_element.append(button);\n",
|
||
" }\n",
|
||
"\n",
|
||
" var fmt_picker_span = $('<span/>');\n",
|
||
"\n",
|
||
" var fmt_picker = $('<select/>');\n",
|
||
" fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
|
||
" fmt_picker_span.append(fmt_picker);\n",
|
||
" nav_element.append(fmt_picker_span);\n",
|
||
" this.format_dropdown = fmt_picker[0];\n",
|
||
"\n",
|
||
" for (var ind in mpl.extensions) {\n",
|
||
" var fmt = mpl.extensions[ind];\n",
|
||
" var option = $(\n",
|
||
" '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
|
||
" fmt_picker.append(option)\n",
|
||
" }\n",
|
||
"\n",
|
||
" // Add hover states to the ui-buttons\n",
|
||
" $( \".ui-button\" ).hover(\n",
|
||
" function() { $(this).addClass(\"ui-state-hover\");},\n",
|
||
" function() { $(this).removeClass(\"ui-state-hover\");}\n",
|
||
" );\n",
|
||
"\n",
|
||
" var status_bar = $('<span class=\"mpl-message\"/>');\n",
|
||
" nav_element.append(status_bar);\n",
|
||
" this.message = status_bar[0];\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
|
||
" // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
|
||
" // which will in turn request a refresh of the image.\n",
|
||
" this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.send_message = function(type, properties) {\n",
|
||
" properties['type'] = type;\n",
|
||
" properties['figure_id'] = this.id;\n",
|
||
" this.ws.send(JSON.stringify(properties));\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.send_draw_message = function() {\n",
|
||
" if (!this.waiting) {\n",
|
||
" this.waiting = true;\n",
|
||
" this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
|
||
" }\n",
|
||
"}\n",
|
||
"\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
|
||
" var format_dropdown = fig.format_dropdown;\n",
|
||
" var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
|
||
" fig.ondownload(fig, format);\n",
|
||
"}\n",
|
||
"\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
|
||
" var size = msg['size'];\n",
|
||
" if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
|
||
" fig._resize_canvas(size[0], size[1]);\n",
|
||
" fig.send_message(\"refresh\", {});\n",
|
||
" };\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
|
||
" var x0 = msg['x0'] / mpl.ratio;\n",
|
||
" var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
|
||
" var x1 = msg['x1'] / mpl.ratio;\n",
|
||
" var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
|
||
" x0 = Math.floor(x0) + 0.5;\n",
|
||
" y0 = Math.floor(y0) + 0.5;\n",
|
||
" x1 = Math.floor(x1) + 0.5;\n",
|
||
" y1 = Math.floor(y1) + 0.5;\n",
|
||
" var min_x = Math.min(x0, x1);\n",
|
||
" var min_y = Math.min(y0, y1);\n",
|
||
" var width = Math.abs(x1 - x0);\n",
|
||
" var height = Math.abs(y1 - y0);\n",
|
||
"\n",
|
||
" fig.rubberband_context.clearRect(\n",
|
||
" 0, 0, fig.canvas.width, fig.canvas.height);\n",
|
||
"\n",
|
||
" fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
|
||
" // Updates the figure title.\n",
|
||
" fig.header.textContent = msg['label'];\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
|
||
" var cursor = msg['cursor'];\n",
|
||
" switch(cursor)\n",
|
||
" {\n",
|
||
" case 0:\n",
|
||
" cursor = 'pointer';\n",
|
||
" break;\n",
|
||
" case 1:\n",
|
||
" cursor = 'default';\n",
|
||
" break;\n",
|
||
" case 2:\n",
|
||
" cursor = 'crosshair';\n",
|
||
" break;\n",
|
||
" case 3:\n",
|
||
" cursor = 'move';\n",
|
||
" break;\n",
|
||
" }\n",
|
||
" fig.rubberband_canvas.style.cursor = cursor;\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_message = function(fig, msg) {\n",
|
||
" fig.message.textContent = msg['message'];\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
|
||
" // Request the server to send over a new figure.\n",
|
||
" fig.send_draw_message();\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
|
||
" fig.image_mode = msg['mode'];\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.updated_canvas_event = function() {\n",
|
||
" // Called whenever the canvas gets updated.\n",
|
||
" this.send_message(\"ack\", {});\n",
|
||
"}\n",
|
||
"\n",
|
||
"// A function to construct a web socket function for onmessage handling.\n",
|
||
"// Called in the figure constructor.\n",
|
||
"mpl.figure.prototype._make_on_message_function = function(fig) {\n",
|
||
" return function socket_on_message(evt) {\n",
|
||
" if (evt.data instanceof Blob) {\n",
|
||
" /* FIXME: We get \"Resource interpreted as Image but\n",
|
||
" * transferred with MIME type text/plain:\" errors on\n",
|
||
" * Chrome. But how to set the MIME type? It doesn't seem\n",
|
||
" * to be part of the websocket stream */\n",
|
||
" evt.data.type = \"image/png\";\n",
|
||
"\n",
|
||
" /* Free the memory for the previous frames */\n",
|
||
" if (fig.imageObj.src) {\n",
|
||
" (window.URL || window.webkitURL).revokeObjectURL(\n",
|
||
" fig.imageObj.src);\n",
|
||
" }\n",
|
||
"\n",
|
||
" fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
|
||
" evt.data);\n",
|
||
" fig.updated_canvas_event();\n",
|
||
" fig.waiting = false;\n",
|
||
" return;\n",
|
||
" }\n",
|
||
" else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
|
||
" fig.imageObj.src = evt.data;\n",
|
||
" fig.updated_canvas_event();\n",
|
||
" fig.waiting = false;\n",
|
||
" return;\n",
|
||
" }\n",
|
||
"\n",
|
||
" var msg = JSON.parse(evt.data);\n",
|
||
" var msg_type = msg['type'];\n",
|
||
"\n",
|
||
" // Call the \"handle_{type}\" callback, which takes\n",
|
||
" // the figure and JSON message as its only arguments.\n",
|
||
" try {\n",
|
||
" var callback = fig[\"handle_\" + msg_type];\n",
|
||
" } catch (e) {\n",
|
||
" console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
|
||
" return;\n",
|
||
" }\n",
|
||
"\n",
|
||
" if (callback) {\n",
|
||
" try {\n",
|
||
" // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
|
||
" callback(fig, msg);\n",
|
||
" } catch (e) {\n",
|
||
" console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
|
||
" }\n",
|
||
" }\n",
|
||
" };\n",
|
||
"}\n",
|
||
"\n",
|
||
"// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
|
||
"mpl.findpos = function(e) {\n",
|
||
" //this section is from http://www.quirksmode.org/js/events_properties.html\n",
|
||
" var targ;\n",
|
||
" if (!e)\n",
|
||
" e = window.event;\n",
|
||
" if (e.target)\n",
|
||
" targ = e.target;\n",
|
||
" else if (e.srcElement)\n",
|
||
" targ = e.srcElement;\n",
|
||
" if (targ.nodeType == 3) // defeat Safari bug\n",
|
||
" targ = targ.parentNode;\n",
|
||
"\n",
|
||
" // jQuery normalizes the pageX and pageY\n",
|
||
" // pageX,Y are the mouse positions relative to the document\n",
|
||
" // offset() returns the position of the element relative to the document\n",
|
||
" var x = e.pageX - $(targ).offset().left;\n",
|
||
" var y = e.pageY - $(targ).offset().top;\n",
|
||
"\n",
|
||
" return {\"x\": x, \"y\": y};\n",
|
||
"};\n",
|
||
"\n",
|
||
"/*\n",
|
||
" * return a copy of an object with only non-object keys\n",
|
||
" * we need this to avoid circular references\n",
|
||
" * http://stackoverflow.com/a/24161582/3208463\n",
|
||
" */\n",
|
||
"function simpleKeys (original) {\n",
|
||
" return Object.keys(original).reduce(function (obj, key) {\n",
|
||
" if (typeof original[key] !== 'object')\n",
|
||
" obj[key] = original[key]\n",
|
||
" return obj;\n",
|
||
" }, {});\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.mouse_event = function(event, name) {\n",
|
||
" var canvas_pos = mpl.findpos(event)\n",
|
||
"\n",
|
||
" if (name === 'button_press')\n",
|
||
" {\n",
|
||
" this.canvas.focus();\n",
|
||
" this.canvas_div.focus();\n",
|
||
" }\n",
|
||
"\n",
|
||
" var x = canvas_pos.x * mpl.ratio;\n",
|
||
" var y = canvas_pos.y * mpl.ratio;\n",
|
||
"\n",
|
||
" this.send_message(name, {x: x, y: y, button: event.button,\n",
|
||
" step: event.step,\n",
|
||
" guiEvent: simpleKeys(event)});\n",
|
||
"\n",
|
||
" /* This prevents the web browser from automatically changing to\n",
|
||
" * the text insertion cursor when the button is pressed. We want\n",
|
||
" * to control all of the cursor setting manually through the\n",
|
||
" * 'cursor' event from matplotlib */\n",
|
||
" event.preventDefault();\n",
|
||
" return false;\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
|
||
" // Handle any extra behaviour associated with a key event\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.key_event = function(event, name) {\n",
|
||
"\n",
|
||
" // Prevent repeat events\n",
|
||
" if (name == 'key_press')\n",
|
||
" {\n",
|
||
" if (event.which === this._key)\n",
|
||
" return;\n",
|
||
" else\n",
|
||
" this._key = event.which;\n",
|
||
" }\n",
|
||
" if (name == 'key_release')\n",
|
||
" this._key = null;\n",
|
||
"\n",
|
||
" var value = '';\n",
|
||
" if (event.ctrlKey && event.which != 17)\n",
|
||
" value += \"ctrl+\";\n",
|
||
" if (event.altKey && event.which != 18)\n",
|
||
" value += \"alt+\";\n",
|
||
" if (event.shiftKey && event.which != 16)\n",
|
||
" value += \"shift+\";\n",
|
||
"\n",
|
||
" value += 'k';\n",
|
||
" value += event.which.toString();\n",
|
||
"\n",
|
||
" this._key_event_extra(event, name);\n",
|
||
"\n",
|
||
" this.send_message(name, {key: value,\n",
|
||
" guiEvent: simpleKeys(event)});\n",
|
||
" return false;\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
|
||
" if (name == 'download') {\n",
|
||
" this.handle_save(this, null);\n",
|
||
" } else {\n",
|
||
" this.send_message(\"toolbar_button\", {name: name});\n",
|
||
" }\n",
|
||
"};\n",
|
||
"\n",
|
||
"mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
|
||
" this.message.textContent = tooltip;\n",
|
||
"};\n",
|
||
"mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
|
||
"\n",
|
||
"mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
|
||
"\n",
|
||
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
|
||
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
||
" // object with the appropriate methods. Currently this is a non binary\n",
|
||
" // socket, so there is still some room for performance tuning.\n",
|
||
" var ws = {};\n",
|
||
"\n",
|
||
" ws.close = function() {\n",
|
||
" comm.close()\n",
|
||
" };\n",
|
||
" ws.send = function(m) {\n",
|
||
" //console.log('sending', m);\n",
|
||
" comm.send(m);\n",
|
||
" };\n",
|
||
" // Register the callback with on_msg.\n",
|
||
" comm.on_msg(function(msg) {\n",
|
||
" //console.log('receiving', msg['content']['data'], msg);\n",
|
||
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
|
||
" ws.onmessage(msg['content']['data'])\n",
|
||
" });\n",
|
||
" return ws;\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.mpl_figure_comm = function(comm, msg) {\n",
|
||
" // This is the function which gets called when the mpl process\n",
|
||
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
||
"\n",
|
||
" var id = msg.content.data.id;\n",
|
||
" // Get hold of the div created by the display call when the Comm\n",
|
||
" // socket was opened in Python.\n",
|
||
" var element = $(\"#\" + id);\n",
|
||
" var ws_proxy = comm_websocket_adapter(comm)\n",
|
||
"\n",
|
||
" function ondownload(figure, format) {\n",
|
||
" window.open(figure.imageObj.src);\n",
|
||
" }\n",
|
||
"\n",
|
||
" var fig = new mpl.figure(id, ws_proxy,\n",
|
||
" ondownload,\n",
|
||
" element.get(0));\n",
|
||
"\n",
|
||
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
||
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
||
" ws_proxy.onopen();\n",
|
||
"\n",
|
||
" fig.parent_element = element.get(0);\n",
|
||
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
||
" if (!fig.cell_info) {\n",
|
||
" console.error(\"Failed to find cell for figure\", id, fig);\n",
|
||
" return;\n",
|
||
" }\n",
|
||
"\n",
|
||
" var output_index = fig.cell_info[2]\n",
|
||
" var cell = fig.cell_info[0];\n",
|
||
"\n",
|
||
"};\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
|
||
" var width = fig.canvas.width/mpl.ratio\n",
|
||
" fig.root.unbind('remove')\n",
|
||
"\n",
|
||
" // Update the output cell to use the data from the current canvas.\n",
|
||
" fig.push_to_output();\n",
|
||
" var dataURL = fig.canvas.toDataURL();\n",
|
||
" // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
|
||
" // the notebook keyboard shortcuts fail.\n",
|
||
" IPython.keyboard_manager.enable()\n",
|
||
" $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
|
||
" fig.close_ws(fig, msg);\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.close_ws = function(fig, msg){\n",
|
||
" fig.send_message('closing', msg);\n",
|
||
" // fig.ws.close()\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
|
||
" // Turn the data on the canvas into data in the output cell.\n",
|
||
" var width = this.canvas.width/mpl.ratio\n",
|
||
" var dataURL = this.canvas.toDataURL();\n",
|
||
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.updated_canvas_event = function() {\n",
|
||
" // Tell IPython that the notebook contents must change.\n",
|
||
" IPython.notebook.set_dirty(true);\n",
|
||
" this.send_message(\"ack\", {});\n",
|
||
" var fig = this;\n",
|
||
" // Wait a second, then push the new image to the DOM so\n",
|
||
" // that it is saved nicely (might be nice to debounce this).\n",
|
||
" setTimeout(function () { fig.push_to_output() }, 1000);\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype._init_toolbar = function() {\n",
|
||
" var fig = this;\n",
|
||
"\n",
|
||
" var nav_element = $('<div/>')\n",
|
||
" nav_element.attr('style', 'width: 100%');\n",
|
||
" this.root.append(nav_element);\n",
|
||
"\n",
|
||
" // Define a callback function for later on.\n",
|
||
" function toolbar_event(event) {\n",
|
||
" return fig.toolbar_button_onclick(event['data']);\n",
|
||
" }\n",
|
||
" function toolbar_mouse_event(event) {\n",
|
||
" return fig.toolbar_button_onmouseover(event['data']);\n",
|
||
" }\n",
|
||
"\n",
|
||
" for(var toolbar_ind in mpl.toolbar_items){\n",
|
||
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
|
||
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
|
||
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
|
||
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
|
||
"\n",
|
||
" if (!name) { continue; };\n",
|
||
"\n",
|
||
" var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
|
||
" button.click(method_name, toolbar_event);\n",
|
||
" button.mouseover(tooltip, toolbar_mouse_event);\n",
|
||
" nav_element.append(button);\n",
|
||
" }\n",
|
||
"\n",
|
||
" // Add the status bar.\n",
|
||
" var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
|
||
" nav_element.append(status_bar);\n",
|
||
" this.message = status_bar[0];\n",
|
||
"\n",
|
||
" // Add the close button to the window.\n",
|
||
" var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
|
||
" var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
|
||
" button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
|
||
" button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
|
||
" buttongrp.append(button);\n",
|
||
" var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
|
||
" titlebar.prepend(buttongrp);\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype._root_extra_style = function(el){\n",
|
||
" var fig = this\n",
|
||
" el.on(\"remove\", function(){\n",
|
||
"\tfig.close_ws(fig, {});\n",
|
||
" });\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype._canvas_extra_style = function(el){\n",
|
||
" // this is important to make the div 'focusable\n",
|
||
" el.attr('tabindex', 0)\n",
|
||
" // reach out to IPython and tell the keyboard manager to turn it's self\n",
|
||
" // off when our div gets focus\n",
|
||
"\n",
|
||
" // location in version 3\n",
|
||
" if (IPython.notebook.keyboard_manager) {\n",
|
||
" IPython.notebook.keyboard_manager.register_events(el);\n",
|
||
" }\n",
|
||
" else {\n",
|
||
" // location in version 2\n",
|
||
" IPython.keyboard_manager.register_events(el);\n",
|
||
" }\n",
|
||
"\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
|
||
" var manager = IPython.notebook.keyboard_manager;\n",
|
||
" if (!manager)\n",
|
||
" manager = IPython.keyboard_manager;\n",
|
||
"\n",
|
||
" // Check for shift+enter\n",
|
||
" if (event.shiftKey && event.which == 13) {\n",
|
||
" this.canvas_div.blur();\n",
|
||
" // select the cell after this one\n",
|
||
" var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
|
||
" IPython.notebook.select(index + 1);\n",
|
||
" }\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
|
||
" fig.ondownload(fig, null);\n",
|
||
"}\n",
|
||
"\n",
|
||
"\n",
|
||
"mpl.find_output_cell = function(html_output) {\n",
|
||
" // Return the cell and output element which can be found *uniquely* in the notebook.\n",
|
||
" // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
|
||
" // IPython event is triggered only after the cells have been serialised, which for\n",
|
||
" // our purposes (turning an active figure into a static one), is too late.\n",
|
||
" var cells = IPython.notebook.get_cells();\n",
|
||
" var ncells = cells.length;\n",
|
||
" for (var i=0; i<ncells; i++) {\n",
|
||
" var cell = cells[i];\n",
|
||
" if (cell.cell_type === 'code'){\n",
|
||
" for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
|
||
" var data = cell.output_area.outputs[j];\n",
|
||
" if (data.data) {\n",
|
||
" // IPython >= 3 moved mimebundle to data attribute of output\n",
|
||
" data = data.data;\n",
|
||
" }\n",
|
||
" if (data['text/html'] == html_output) {\n",
|
||
" return [cell, data, j];\n",
|
||
" }\n",
|
||
" }\n",
|
||
" }\n",
|
||
" }\n",
|
||
"}\n",
|
||
"\n",
|
||
"// Register the function which deals with the matplotlib target/channel.\n",
|
||
"// The kernel may be null if the page has been refreshed.\n",
|
||
"if (IPython.notebook.kernel != null) {\n",
|
||
" IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
|
||
"}\n"
|
||
],
|
||
"text/plain": [
|
||
"<IPython.core.display.Javascript object>"
|
||
]
|
||
},
|
||
"metadata": {},
|
||
"output_type": "display_data"
|
||
},
|
||
{
|
||
"data": {
|
||
"text/html": [
|
||
"<img src=\"data:image/png;base64,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\" width=\"640\">"
|
||
],
|
||
"text/plain": [
|
||
"<IPython.core.display.HTML object>"
|
||
]
|
||
},
|
||
"metadata": {},
|
||
"output_type": "display_data"
|
||
}
|
||
],
|
||
"source": [
|
||
"#live_plot_rgb_splines(14, 15, 13, live=False, show_title=False)\n",
|
||
"live_plot_rgb_splines(45, 46, 44, spline_s=0.08, max_stdev=1.0, live=False, show_title=False, save_svg='/tmp/raw_plot_cheap_rgb.svg')"
|
||
]
|
||
},
|
||
{
|
||
"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": 118,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"application/javascript": [
|
||
"/* Put everything inside the global mpl namespace */\n",
|
||
"window.mpl = {};\n",
|
||
"\n",
|
||
"\n",
|
||
"mpl.get_websocket_type = function() {\n",
|
||
" if (typeof(WebSocket) !== 'undefined') {\n",
|
||
" return WebSocket;\n",
|
||
" } else if (typeof(MozWebSocket) !== 'undefined') {\n",
|
||
" return MozWebSocket;\n",
|
||
" } else {\n",
|
||
" alert('Your browser does not have WebSocket support.' +\n",
|
||
" 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
|
||
" 'Firefox 4 and 5 are also supported but you ' +\n",
|
||
" 'have to enable WebSockets in about:config.');\n",
|
||
" };\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
|
||
" this.id = figure_id;\n",
|
||
"\n",
|
||
" this.ws = websocket;\n",
|
||
"\n",
|
||
" this.supports_binary = (this.ws.binaryType != undefined);\n",
|
||
"\n",
|
||
" if (!this.supports_binary) {\n",
|
||
" var warnings = document.getElementById(\"mpl-warnings\");\n",
|
||
" if (warnings) {\n",
|
||
" warnings.style.display = 'block';\n",
|
||
" warnings.textContent = (\n",
|
||
" \"This browser does not support binary websocket messages. \" +\n",
|
||
" \"Performance may be slow.\");\n",
|
||
" }\n",
|
||
" }\n",
|
||
"\n",
|
||
" this.imageObj = new Image();\n",
|
||
"\n",
|
||
" this.context = undefined;\n",
|
||
" this.message = undefined;\n",
|
||
" this.canvas = undefined;\n",
|
||
" this.rubberband_canvas = undefined;\n",
|
||
" this.rubberband_context = undefined;\n",
|
||
" this.format_dropdown = undefined;\n",
|
||
"\n",
|
||
" this.image_mode = 'full';\n",
|
||
"\n",
|
||
" this.root = $('<div/>');\n",
|
||
" this._root_extra_style(this.root)\n",
|
||
" this.root.attr('style', 'display: inline-block');\n",
|
||
"\n",
|
||
" $(parent_element).append(this.root);\n",
|
||
"\n",
|
||
" this._init_header(this);\n",
|
||
" this._init_canvas(this);\n",
|
||
" this._init_toolbar(this);\n",
|
||
"\n",
|
||
" var fig = this;\n",
|
||
"\n",
|
||
" this.waiting = false;\n",
|
||
"\n",
|
||
" this.ws.onopen = function () {\n",
|
||
" fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
|
||
" fig.send_message(\"send_image_mode\", {});\n",
|
||
" if (mpl.ratio != 1) {\n",
|
||
" fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
|
||
" }\n",
|
||
" fig.send_message(\"refresh\", {});\n",
|
||
" }\n",
|
||
"\n",
|
||
" this.imageObj.onload = function() {\n",
|
||
" if (fig.image_mode == 'full') {\n",
|
||
" // Full images could contain transparency (where diff images\n",
|
||
" // almost always do), so we need to clear the canvas so that\n",
|
||
" // there is no ghosting.\n",
|
||
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
||
" }\n",
|
||
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
||
" };\n",
|
||
"\n",
|
||
" this.imageObj.onunload = function() {\n",
|
||
" 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 backingStore = this.context.backingStorePixelRatio ||\n",
|
||
"\tthis.context.webkitBackingStorePixelRatio ||\n",
|
||
"\tthis.context.mozBackingStorePixelRatio ||\n",
|
||
"\tthis.context.msBackingStorePixelRatio ||\n",
|
||
"\tthis.context.oBackingStorePixelRatio ||\n",
|
||
"\tthis.context.backingStorePixelRatio || 1;\n",
|
||
"\n",
|
||
" mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
|
||
"\n",
|
||
" var rubberband = $('<canvas/>');\n",
|
||
" rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
|
||
"\n",
|
||
" var pass_mouse_events = true;\n",
|
||
"\n",
|
||
" canvas_div.resizable({\n",
|
||
" start: function(event, ui) {\n",
|
||
" pass_mouse_events = false;\n",
|
||
" },\n",
|
||
" resize: function(event, ui) {\n",
|
||
" fig.request_resize(ui.size.width, ui.size.height);\n",
|
||
" },\n",
|
||
" stop: function(event, ui) {\n",
|
||
" pass_mouse_events = true;\n",
|
||
" fig.request_resize(ui.size.width, ui.size.height);\n",
|
||
" },\n",
|
||
" });\n",
|
||
"\n",
|
||
" function mouse_event_fn(event) {\n",
|
||
" if (pass_mouse_events)\n",
|
||
" return fig.mouse_event(event, event['data']);\n",
|
||
" }\n",
|
||
"\n",
|
||
" rubberband.mousedown('button_press', mouse_event_fn);\n",
|
||
" rubberband.mouseup('button_release', mouse_event_fn);\n",
|
||
" // Throttle sequential mouse events to 1 every 20ms.\n",
|
||
" rubberband.mousemove('motion_notify', mouse_event_fn);\n",
|
||
"\n",
|
||
" rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
|
||
" rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
|
||
"\n",
|
||
" canvas_div.on(\"wheel\", function (event) {\n",
|
||
" event = event.originalEvent;\n",
|
||
" event['data'] = 'scroll'\n",
|
||
" if (event.deltaY < 0) {\n",
|
||
" event.step = 1;\n",
|
||
" } else {\n",
|
||
" event.step = -1;\n",
|
||
" }\n",
|
||
" mouse_event_fn(event);\n",
|
||
" });\n",
|
||
"\n",
|
||
" canvas_div.append(canvas);\n",
|
||
" canvas_div.append(rubberband);\n",
|
||
"\n",
|
||
" this.rubberband = rubberband;\n",
|
||
" this.rubberband_canvas = rubberband[0];\n",
|
||
" this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
|
||
" this.rubberband_context.strokeStyle = \"#000000\";\n",
|
||
"\n",
|
||
" this._resize_canvas = function(width, height) {\n",
|
||
" // Keep the size of the canvas, canvas container, and rubber band\n",
|
||
" // canvas in synch.\n",
|
||
" canvas_div.css('width', width)\n",
|
||
" canvas_div.css('height', height)\n",
|
||
"\n",
|
||
" canvas.attr('width', width * mpl.ratio);\n",
|
||
" canvas.attr('height', height * mpl.ratio);\n",
|
||
" canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
|
||
"\n",
|
||
" rubberband.attr('width', width);\n",
|
||
" rubberband.attr('height', height);\n",
|
||
" }\n",
|
||
"\n",
|
||
" // Set the figure to an initial 600x600px, this will subsequently be updated\n",
|
||
" // upon first draw.\n",
|
||
" this._resize_canvas(600, 600);\n",
|
||
"\n",
|
||
" // Disable right mouse context menu.\n",
|
||
" $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
|
||
" return false;\n",
|
||
" });\n",
|
||
"\n",
|
||
" function set_focus () {\n",
|
||
" canvas.focus();\n",
|
||
" canvas_div.focus();\n",
|
||
" }\n",
|
||
"\n",
|
||
" window.setTimeout(set_focus, 100);\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype._init_toolbar = function() {\n",
|
||
" var fig = this;\n",
|
||
"\n",
|
||
" var nav_element = $('<div/>')\n",
|
||
" nav_element.attr('style', 'width: 100%');\n",
|
||
" this.root.append(nav_element);\n",
|
||
"\n",
|
||
" // Define a callback function for later on.\n",
|
||
" function toolbar_event(event) {\n",
|
||
" return fig.toolbar_button_onclick(event['data']);\n",
|
||
" }\n",
|
||
" function toolbar_mouse_event(event) {\n",
|
||
" return fig.toolbar_button_onmouseover(event['data']);\n",
|
||
" }\n",
|
||
"\n",
|
||
" for(var toolbar_ind in mpl.toolbar_items) {\n",
|
||
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
|
||
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
|
||
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
|
||
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
|
||
"\n",
|
||
" if (!name) {\n",
|
||
" // put a spacer in here.\n",
|
||
" continue;\n",
|
||
" }\n",
|
||
" var button = $('<button/>');\n",
|
||
" button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
|
||
" 'ui-button-icon-only');\n",
|
||
" button.attr('role', 'button');\n",
|
||
" button.attr('aria-disabled', 'false');\n",
|
||
" button.click(method_name, toolbar_event);\n",
|
||
" button.mouseover(tooltip, toolbar_mouse_event);\n",
|
||
"\n",
|
||
" var icon_img = $('<span/>');\n",
|
||
" icon_img.addClass('ui-button-icon-primary ui-icon');\n",
|
||
" icon_img.addClass(image);\n",
|
||
" icon_img.addClass('ui-corner-all');\n",
|
||
"\n",
|
||
" var tooltip_span = $('<span/>');\n",
|
||
" tooltip_span.addClass('ui-button-text');\n",
|
||
" tooltip_span.html(tooltip);\n",
|
||
"\n",
|
||
" button.append(icon_img);\n",
|
||
" button.append(tooltip_span);\n",
|
||
"\n",
|
||
" nav_element.append(button);\n",
|
||
" }\n",
|
||
"\n",
|
||
" var fmt_picker_span = $('<span/>');\n",
|
||
"\n",
|
||
" var fmt_picker = $('<select/>');\n",
|
||
" fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
|
||
" fmt_picker_span.append(fmt_picker);\n",
|
||
" nav_element.append(fmt_picker_span);\n",
|
||
" this.format_dropdown = fmt_picker[0];\n",
|
||
"\n",
|
||
" for (var ind in mpl.extensions) {\n",
|
||
" var fmt = mpl.extensions[ind];\n",
|
||
" var option = $(\n",
|
||
" '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
|
||
" fmt_picker.append(option)\n",
|
||
" }\n",
|
||
"\n",
|
||
" // Add hover states to the ui-buttons\n",
|
||
" $( \".ui-button\" ).hover(\n",
|
||
" function() { $(this).addClass(\"ui-state-hover\");},\n",
|
||
" function() { $(this).removeClass(\"ui-state-hover\");}\n",
|
||
" );\n",
|
||
"\n",
|
||
" var status_bar = $('<span class=\"mpl-message\"/>');\n",
|
||
" nav_element.append(status_bar);\n",
|
||
" this.message = status_bar[0];\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
|
||
" // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
|
||
" // which will in turn request a refresh of the image.\n",
|
||
" this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.send_message = function(type, properties) {\n",
|
||
" properties['type'] = type;\n",
|
||
" properties['figure_id'] = this.id;\n",
|
||
" this.ws.send(JSON.stringify(properties));\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.send_draw_message = function() {\n",
|
||
" if (!this.waiting) {\n",
|
||
" this.waiting = true;\n",
|
||
" this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
|
||
" }\n",
|
||
"}\n",
|
||
"\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
|
||
" var format_dropdown = fig.format_dropdown;\n",
|
||
" var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
|
||
" fig.ondownload(fig, format);\n",
|
||
"}\n",
|
||
"\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
|
||
" var size = msg['size'];\n",
|
||
" if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
|
||
" fig._resize_canvas(size[0], size[1]);\n",
|
||
" fig.send_message(\"refresh\", {});\n",
|
||
" };\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
|
||
" var x0 = msg['x0'] / mpl.ratio;\n",
|
||
" var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
|
||
" var x1 = msg['x1'] / mpl.ratio;\n",
|
||
" var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
|
||
" x0 = Math.floor(x0) + 0.5;\n",
|
||
" y0 = Math.floor(y0) + 0.5;\n",
|
||
" x1 = Math.floor(x1) + 0.5;\n",
|
||
" y1 = Math.floor(y1) + 0.5;\n",
|
||
" var min_x = Math.min(x0, x1);\n",
|
||
" var min_y = Math.min(y0, y1);\n",
|
||
" var width = Math.abs(x1 - x0);\n",
|
||
" var height = Math.abs(y1 - y0);\n",
|
||
"\n",
|
||
" fig.rubberband_context.clearRect(\n",
|
||
" 0, 0, fig.canvas.width, fig.canvas.height);\n",
|
||
"\n",
|
||
" fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
|
||
" // Updates the figure title.\n",
|
||
" fig.header.textContent = msg['label'];\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
|
||
" var cursor = msg['cursor'];\n",
|
||
" switch(cursor)\n",
|
||
" {\n",
|
||
" case 0:\n",
|
||
" cursor = 'pointer';\n",
|
||
" break;\n",
|
||
" case 1:\n",
|
||
" cursor = 'default';\n",
|
||
" break;\n",
|
||
" case 2:\n",
|
||
" cursor = 'crosshair';\n",
|
||
" break;\n",
|
||
" case 3:\n",
|
||
" cursor = 'move';\n",
|
||
" break;\n",
|
||
" }\n",
|
||
" fig.rubberband_canvas.style.cursor = cursor;\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_message = function(fig, msg) {\n",
|
||
" fig.message.textContent = msg['message'];\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
|
||
" // Request the server to send over a new figure.\n",
|
||
" fig.send_draw_message();\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
|
||
" fig.image_mode = msg['mode'];\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.updated_canvas_event = function() {\n",
|
||
" // Called whenever the canvas gets updated.\n",
|
||
" this.send_message(\"ack\", {});\n",
|
||
"}\n",
|
||
"\n",
|
||
"// A function to construct a web socket function for onmessage handling.\n",
|
||
"// Called in the figure constructor.\n",
|
||
"mpl.figure.prototype._make_on_message_function = function(fig) {\n",
|
||
" return function socket_on_message(evt) {\n",
|
||
" if (evt.data instanceof Blob) {\n",
|
||
" /* FIXME: We get \"Resource interpreted as Image but\n",
|
||
" * transferred with MIME type text/plain:\" errors on\n",
|
||
" * Chrome. But how to set the MIME type? It doesn't seem\n",
|
||
" * to be part of the websocket stream */\n",
|
||
" evt.data.type = \"image/png\";\n",
|
||
"\n",
|
||
" /* Free the memory for the previous frames */\n",
|
||
" if (fig.imageObj.src) {\n",
|
||
" (window.URL || window.webkitURL).revokeObjectURL(\n",
|
||
" fig.imageObj.src);\n",
|
||
" }\n",
|
||
"\n",
|
||
" fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
|
||
" evt.data);\n",
|
||
" fig.updated_canvas_event();\n",
|
||
" fig.waiting = false;\n",
|
||
" return;\n",
|
||
" }\n",
|
||
" else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
|
||
" fig.imageObj.src = evt.data;\n",
|
||
" fig.updated_canvas_event();\n",
|
||
" fig.waiting = false;\n",
|
||
" return;\n",
|
||
" }\n",
|
||
"\n",
|
||
" var msg = JSON.parse(evt.data);\n",
|
||
" var msg_type = msg['type'];\n",
|
||
"\n",
|
||
" // Call the \"handle_{type}\" callback, which takes\n",
|
||
" // the figure and JSON message as its only arguments.\n",
|
||
" try {\n",
|
||
" var callback = fig[\"handle_\" + msg_type];\n",
|
||
" } catch (e) {\n",
|
||
" console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
|
||
" return;\n",
|
||
" }\n",
|
||
"\n",
|
||
" if (callback) {\n",
|
||
" try {\n",
|
||
" // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
|
||
" callback(fig, msg);\n",
|
||
" } catch (e) {\n",
|
||
" console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
|
||
" }\n",
|
||
" }\n",
|
||
" };\n",
|
||
"}\n",
|
||
"\n",
|
||
"// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
|
||
"mpl.findpos = function(e) {\n",
|
||
" //this section is from http://www.quirksmode.org/js/events_properties.html\n",
|
||
" var targ;\n",
|
||
" if (!e)\n",
|
||
" e = window.event;\n",
|
||
" if (e.target)\n",
|
||
" targ = e.target;\n",
|
||
" else if (e.srcElement)\n",
|
||
" targ = e.srcElement;\n",
|
||
" if (targ.nodeType == 3) // defeat Safari bug\n",
|
||
" targ = targ.parentNode;\n",
|
||
"\n",
|
||
" // jQuery normalizes the pageX and pageY\n",
|
||
" // pageX,Y are the mouse positions relative to the document\n",
|
||
" // offset() returns the position of the element relative to the document\n",
|
||
" var x = e.pageX - $(targ).offset().left;\n",
|
||
" var y = e.pageY - $(targ).offset().top;\n",
|
||
"\n",
|
||
" return {\"x\": x, \"y\": y};\n",
|
||
"};\n",
|
||
"\n",
|
||
"/*\n",
|
||
" * return a copy of an object with only non-object keys\n",
|
||
" * we need this to avoid circular references\n",
|
||
" * http://stackoverflow.com/a/24161582/3208463\n",
|
||
" */\n",
|
||
"function simpleKeys (original) {\n",
|
||
" return Object.keys(original).reduce(function (obj, key) {\n",
|
||
" if (typeof original[key] !== 'object')\n",
|
||
" obj[key] = original[key]\n",
|
||
" return obj;\n",
|
||
" }, {});\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.mouse_event = function(event, name) {\n",
|
||
" var canvas_pos = mpl.findpos(event)\n",
|
||
"\n",
|
||
" if (name === 'button_press')\n",
|
||
" {\n",
|
||
" this.canvas.focus();\n",
|
||
" this.canvas_div.focus();\n",
|
||
" }\n",
|
||
"\n",
|
||
" var x = canvas_pos.x * mpl.ratio;\n",
|
||
" var y = canvas_pos.y * mpl.ratio;\n",
|
||
"\n",
|
||
" this.send_message(name, {x: x, y: y, button: event.button,\n",
|
||
" step: event.step,\n",
|
||
" guiEvent: simpleKeys(event)});\n",
|
||
"\n",
|
||
" /* This prevents the web browser from automatically changing to\n",
|
||
" * the text insertion cursor when the button is pressed. We want\n",
|
||
" * to control all of the cursor setting manually through the\n",
|
||
" * 'cursor' event from matplotlib */\n",
|
||
" event.preventDefault();\n",
|
||
" return false;\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
|
||
" // Handle any extra behaviour associated with a key event\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.key_event = function(event, name) {\n",
|
||
"\n",
|
||
" // Prevent repeat events\n",
|
||
" if (name == 'key_press')\n",
|
||
" {\n",
|
||
" if (event.which === this._key)\n",
|
||
" return;\n",
|
||
" else\n",
|
||
" this._key = event.which;\n",
|
||
" }\n",
|
||
" if (name == 'key_release')\n",
|
||
" this._key = null;\n",
|
||
"\n",
|
||
" var value = '';\n",
|
||
" if (event.ctrlKey && event.which != 17)\n",
|
||
" value += \"ctrl+\";\n",
|
||
" if (event.altKey && event.which != 18)\n",
|
||
" value += \"alt+\";\n",
|
||
" if (event.shiftKey && event.which != 16)\n",
|
||
" value += \"shift+\";\n",
|
||
"\n",
|
||
" value += 'k';\n",
|
||
" value += event.which.toString();\n",
|
||
"\n",
|
||
" this._key_event_extra(event, name);\n",
|
||
"\n",
|
||
" this.send_message(name, {key: value,\n",
|
||
" guiEvent: simpleKeys(event)});\n",
|
||
" return false;\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
|
||
" if (name == 'download') {\n",
|
||
" this.handle_save(this, null);\n",
|
||
" } else {\n",
|
||
" this.send_message(\"toolbar_button\", {name: name});\n",
|
||
" }\n",
|
||
"};\n",
|
||
"\n",
|
||
"mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
|
||
" this.message.textContent = tooltip;\n",
|
||
"};\n",
|
||
"mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
|
||
"\n",
|
||
"mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
|
||
"\n",
|
||
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
|
||
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
||
" // object with the appropriate methods. Currently this is a non binary\n",
|
||
" // socket, so there is still some room for performance tuning.\n",
|
||
" var ws = {};\n",
|
||
"\n",
|
||
" ws.close = function() {\n",
|
||
" comm.close()\n",
|
||
" };\n",
|
||
" ws.send = function(m) {\n",
|
||
" //console.log('sending', m);\n",
|
||
" comm.send(m);\n",
|
||
" };\n",
|
||
" // Register the callback with on_msg.\n",
|
||
" comm.on_msg(function(msg) {\n",
|
||
" //console.log('receiving', msg['content']['data'], msg);\n",
|
||
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
|
||
" ws.onmessage(msg['content']['data'])\n",
|
||
" });\n",
|
||
" return ws;\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.mpl_figure_comm = function(comm, msg) {\n",
|
||
" // This is the function which gets called when the mpl process\n",
|
||
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
||
"\n",
|
||
" var id = msg.content.data.id;\n",
|
||
" // Get hold of the div created by the display call when the Comm\n",
|
||
" // socket was opened in Python.\n",
|
||
" var element = $(\"#\" + id);\n",
|
||
" var ws_proxy = comm_websocket_adapter(comm)\n",
|
||
"\n",
|
||
" function ondownload(figure, format) {\n",
|
||
" window.open(figure.imageObj.src);\n",
|
||
" }\n",
|
||
"\n",
|
||
" var fig = new mpl.figure(id, ws_proxy,\n",
|
||
" ondownload,\n",
|
||
" element.get(0));\n",
|
||
"\n",
|
||
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
||
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
||
" ws_proxy.onopen();\n",
|
||
"\n",
|
||
" fig.parent_element = element.get(0);\n",
|
||
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
||
" if (!fig.cell_info) {\n",
|
||
" console.error(\"Failed to find cell for figure\", id, fig);\n",
|
||
" return;\n",
|
||
" }\n",
|
||
"\n",
|
||
" var output_index = fig.cell_info[2]\n",
|
||
" var cell = fig.cell_info[0];\n",
|
||
"\n",
|
||
"};\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
|
||
" var width = fig.canvas.width/mpl.ratio\n",
|
||
" fig.root.unbind('remove')\n",
|
||
"\n",
|
||
" // Update the output cell to use the data from the current canvas.\n",
|
||
" fig.push_to_output();\n",
|
||
" var dataURL = fig.canvas.toDataURL();\n",
|
||
" // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
|
||
" // the notebook keyboard shortcuts fail.\n",
|
||
" IPython.keyboard_manager.enable()\n",
|
||
" $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
|
||
" fig.close_ws(fig, msg);\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.close_ws = function(fig, msg){\n",
|
||
" fig.send_message('closing', msg);\n",
|
||
" // fig.ws.close()\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
|
||
" // Turn the data on the canvas into data in the output cell.\n",
|
||
" var width = this.canvas.width/mpl.ratio\n",
|
||
" var dataURL = this.canvas.toDataURL();\n",
|
||
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.updated_canvas_event = function() {\n",
|
||
" // Tell IPython that the notebook contents must change.\n",
|
||
" IPython.notebook.set_dirty(true);\n",
|
||
" this.send_message(\"ack\", {});\n",
|
||
" var fig = this;\n",
|
||
" // Wait a second, then push the new image to the DOM so\n",
|
||
" // that it is saved nicely (might be nice to debounce this).\n",
|
||
" setTimeout(function () { fig.push_to_output() }, 1000);\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype._init_toolbar = function() {\n",
|
||
" var fig = this;\n",
|
||
"\n",
|
||
" var nav_element = $('<div/>')\n",
|
||
" nav_element.attr('style', 'width: 100%');\n",
|
||
" this.root.append(nav_element);\n",
|
||
"\n",
|
||
" // Define a callback function for later on.\n",
|
||
" function toolbar_event(event) {\n",
|
||
" return fig.toolbar_button_onclick(event['data']);\n",
|
||
" }\n",
|
||
" function toolbar_mouse_event(event) {\n",
|
||
" return fig.toolbar_button_onmouseover(event['data']);\n",
|
||
" }\n",
|
||
"\n",
|
||
" for(var toolbar_ind in mpl.toolbar_items){\n",
|
||
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
|
||
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
|
||
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
|
||
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
|
||
"\n",
|
||
" if (!name) { continue; };\n",
|
||
"\n",
|
||
" var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
|
||
" button.click(method_name, toolbar_event);\n",
|
||
" button.mouseover(tooltip, toolbar_mouse_event);\n",
|
||
" nav_element.append(button);\n",
|
||
" }\n",
|
||
"\n",
|
||
" // Add the status bar.\n",
|
||
" var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
|
||
" nav_element.append(status_bar);\n",
|
||
" this.message = status_bar[0];\n",
|
||
"\n",
|
||
" // Add the close button to the window.\n",
|
||
" var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
|
||
" var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
|
||
" button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
|
||
" button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
|
||
" buttongrp.append(button);\n",
|
||
" var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
|
||
" titlebar.prepend(buttongrp);\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype._root_extra_style = function(el){\n",
|
||
" var fig = this\n",
|
||
" el.on(\"remove\", function(){\n",
|
||
"\tfig.close_ws(fig, {});\n",
|
||
" });\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype._canvas_extra_style = function(el){\n",
|
||
" // this is important to make the div 'focusable\n",
|
||
" el.attr('tabindex', 0)\n",
|
||
" // reach out to IPython and tell the keyboard manager to turn it's self\n",
|
||
" // off when our div gets focus\n",
|
||
"\n",
|
||
" // location in version 3\n",
|
||
" if (IPython.notebook.keyboard_manager) {\n",
|
||
" IPython.notebook.keyboard_manager.register_events(el);\n",
|
||
" }\n",
|
||
" else {\n",
|
||
" // location in version 2\n",
|
||
" IPython.keyboard_manager.register_events(el);\n",
|
||
" }\n",
|
||
"\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
|
||
" var manager = IPython.notebook.keyboard_manager;\n",
|
||
" if (!manager)\n",
|
||
" manager = IPython.keyboard_manager;\n",
|
||
"\n",
|
||
" // Check for shift+enter\n",
|
||
" if (event.shiftKey && event.which == 13) {\n",
|
||
" this.canvas_div.blur();\n",
|
||
" // select the cell after this one\n",
|
||
" var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
|
||
" IPython.notebook.select(index + 1);\n",
|
||
" }\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
|
||
" fig.ondownload(fig, null);\n",
|
||
"}\n",
|
||
"\n",
|
||
"\n",
|
||
"mpl.find_output_cell = function(html_output) {\n",
|
||
" // Return the cell and output element which can be found *uniquely* in the notebook.\n",
|
||
" // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
|
||
" // IPython event is triggered only after the cells have been serialised, which for\n",
|
||
" // our purposes (turning an active figure into a static one), is too late.\n",
|
||
" var cells = IPython.notebook.get_cells();\n",
|
||
" var ncells = cells.length;\n",
|
||
" for (var i=0; i<ncells; i++) {\n",
|
||
" var cell = cells[i];\n",
|
||
" if (cell.cell_type === 'code'){\n",
|
||
" for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
|
||
" var data = cell.output_area.outputs[j];\n",
|
||
" if (data.data) {\n",
|
||
" // IPython >= 3 moved mimebundle to data attribute of output\n",
|
||
" data = data.data;\n",
|
||
" }\n",
|
||
" if (data['text/html'] == html_output) {\n",
|
||
" return [cell, data, j];\n",
|
||
" }\n",
|
||
" }\n",
|
||
" }\n",
|
||
" }\n",
|
||
"}\n",
|
||
"\n",
|
||
"// Register the function which deals with the matplotlib target/channel.\n",
|
||
"// The kernel may be null if the page has been refreshed.\n",
|
||
"if (IPython.notebook.kernel != null) {\n",
|
||
" IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
|
||
"}\n"
|
||
],
|
||
"text/plain": [
|
||
"<IPython.core.display.Javascript object>"
|
||
]
|
||
},
|
||
"metadata": {},
|
||
"output_type": "display_data"
|
||
},
|
||
{
|
||
"data": {
|
||
"text/html": [
|
||
"<img src=\"data:image/png;base64,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\" width=\"640\">"
|
||
],
|
||
"text/plain": [
|
||
"<IPython.core.display.HTML object>"
|
||
]
|
||
},
|
||
"metadata": {},
|
||
"output_type": "display_data"
|
||
}
|
||
],
|
||
"source": [
|
||
"live_plot_rgb_splines(42, 43, 40, spline_s=0.01, max_stdev=1.0, live=False)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 119,
|
||
"metadata": {
|
||
"scrolled": false
|
||
},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"application/javascript": [
|
||
"/* Put everything inside the global mpl namespace */\n",
|
||
"window.mpl = {};\n",
|
||
"\n",
|
||
"\n",
|
||
"mpl.get_websocket_type = function() {\n",
|
||
" if (typeof(WebSocket) !== 'undefined') {\n",
|
||
" return WebSocket;\n",
|
||
" } else if (typeof(MozWebSocket) !== 'undefined') {\n",
|
||
" return MozWebSocket;\n",
|
||
" } else {\n",
|
||
" alert('Your browser does not have WebSocket support.' +\n",
|
||
" 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
|
||
" 'Firefox 4 and 5 are also supported but you ' +\n",
|
||
" 'have to enable WebSockets in about:config.');\n",
|
||
" };\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
|
||
" this.id = figure_id;\n",
|
||
"\n",
|
||
" this.ws = websocket;\n",
|
||
"\n",
|
||
" this.supports_binary = (this.ws.binaryType != undefined);\n",
|
||
"\n",
|
||
" if (!this.supports_binary) {\n",
|
||
" var warnings = document.getElementById(\"mpl-warnings\");\n",
|
||
" if (warnings) {\n",
|
||
" warnings.style.display = 'block';\n",
|
||
" warnings.textContent = (\n",
|
||
" \"This browser does not support binary websocket messages. \" +\n",
|
||
" \"Performance may be slow.\");\n",
|
||
" }\n",
|
||
" }\n",
|
||
"\n",
|
||
" this.imageObj = new Image();\n",
|
||
"\n",
|
||
" this.context = undefined;\n",
|
||
" this.message = undefined;\n",
|
||
" this.canvas = undefined;\n",
|
||
" this.rubberband_canvas = undefined;\n",
|
||
" this.rubberband_context = undefined;\n",
|
||
" this.format_dropdown = undefined;\n",
|
||
"\n",
|
||
" this.image_mode = 'full';\n",
|
||
"\n",
|
||
" this.root = $('<div/>');\n",
|
||
" this._root_extra_style(this.root)\n",
|
||
" this.root.attr('style', 'display: inline-block');\n",
|
||
"\n",
|
||
" $(parent_element).append(this.root);\n",
|
||
"\n",
|
||
" this._init_header(this);\n",
|
||
" this._init_canvas(this);\n",
|
||
" this._init_toolbar(this);\n",
|
||
"\n",
|
||
" var fig = this;\n",
|
||
"\n",
|
||
" this.waiting = false;\n",
|
||
"\n",
|
||
" this.ws.onopen = function () {\n",
|
||
" fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
|
||
" fig.send_message(\"send_image_mode\", {});\n",
|
||
" if (mpl.ratio != 1) {\n",
|
||
" fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
|
||
" }\n",
|
||
" fig.send_message(\"refresh\", {});\n",
|
||
" }\n",
|
||
"\n",
|
||
" this.imageObj.onload = function() {\n",
|
||
" if (fig.image_mode == 'full') {\n",
|
||
" // Full images could contain transparency (where diff images\n",
|
||
" // almost always do), so we need to clear the canvas so that\n",
|
||
" // there is no ghosting.\n",
|
||
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
||
" }\n",
|
||
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
||
" };\n",
|
||
"\n",
|
||
" this.imageObj.onunload = function() {\n",
|
||
" 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 backingStore = this.context.backingStorePixelRatio ||\n",
|
||
"\tthis.context.webkitBackingStorePixelRatio ||\n",
|
||
"\tthis.context.mozBackingStorePixelRatio ||\n",
|
||
"\tthis.context.msBackingStorePixelRatio ||\n",
|
||
"\tthis.context.oBackingStorePixelRatio ||\n",
|
||
"\tthis.context.backingStorePixelRatio || 1;\n",
|
||
"\n",
|
||
" mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
|
||
"\n",
|
||
" var rubberband = $('<canvas/>');\n",
|
||
" rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
|
||
"\n",
|
||
" var pass_mouse_events = true;\n",
|
||
"\n",
|
||
" canvas_div.resizable({\n",
|
||
" start: function(event, ui) {\n",
|
||
" pass_mouse_events = false;\n",
|
||
" },\n",
|
||
" resize: function(event, ui) {\n",
|
||
" fig.request_resize(ui.size.width, ui.size.height);\n",
|
||
" },\n",
|
||
" stop: function(event, ui) {\n",
|
||
" pass_mouse_events = true;\n",
|
||
" fig.request_resize(ui.size.width, ui.size.height);\n",
|
||
" },\n",
|
||
" });\n",
|
||
"\n",
|
||
" function mouse_event_fn(event) {\n",
|
||
" if (pass_mouse_events)\n",
|
||
" return fig.mouse_event(event, event['data']);\n",
|
||
" }\n",
|
||
"\n",
|
||
" rubberband.mousedown('button_press', mouse_event_fn);\n",
|
||
" rubberband.mouseup('button_release', mouse_event_fn);\n",
|
||
" // Throttle sequential mouse events to 1 every 20ms.\n",
|
||
" rubberband.mousemove('motion_notify', mouse_event_fn);\n",
|
||
"\n",
|
||
" rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
|
||
" rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
|
||
"\n",
|
||
" canvas_div.on(\"wheel\", function (event) {\n",
|
||
" event = event.originalEvent;\n",
|
||
" event['data'] = 'scroll'\n",
|
||
" if (event.deltaY < 0) {\n",
|
||
" event.step = 1;\n",
|
||
" } else {\n",
|
||
" event.step = -1;\n",
|
||
" }\n",
|
||
" mouse_event_fn(event);\n",
|
||
" });\n",
|
||
"\n",
|
||
" canvas_div.append(canvas);\n",
|
||
" canvas_div.append(rubberband);\n",
|
||
"\n",
|
||
" this.rubberband = rubberband;\n",
|
||
" this.rubberband_canvas = rubberband[0];\n",
|
||
" this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
|
||
" this.rubberband_context.strokeStyle = \"#000000\";\n",
|
||
"\n",
|
||
" this._resize_canvas = function(width, height) {\n",
|
||
" // Keep the size of the canvas, canvas container, and rubber band\n",
|
||
" // canvas in synch.\n",
|
||
" canvas_div.css('width', width)\n",
|
||
" canvas_div.css('height', height)\n",
|
||
"\n",
|
||
" canvas.attr('width', width * mpl.ratio);\n",
|
||
" canvas.attr('height', height * mpl.ratio);\n",
|
||
" canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
|
||
"\n",
|
||
" rubberband.attr('width', width);\n",
|
||
" rubberband.attr('height', height);\n",
|
||
" }\n",
|
||
"\n",
|
||
" // Set the figure to an initial 600x600px, this will subsequently be updated\n",
|
||
" // upon first draw.\n",
|
||
" this._resize_canvas(600, 600);\n",
|
||
"\n",
|
||
" // Disable right mouse context menu.\n",
|
||
" $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
|
||
" return false;\n",
|
||
" });\n",
|
||
"\n",
|
||
" function set_focus () {\n",
|
||
" canvas.focus();\n",
|
||
" canvas_div.focus();\n",
|
||
" }\n",
|
||
"\n",
|
||
" window.setTimeout(set_focus, 100);\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype._init_toolbar = function() {\n",
|
||
" var fig = this;\n",
|
||
"\n",
|
||
" var nav_element = $('<div/>')\n",
|
||
" nav_element.attr('style', 'width: 100%');\n",
|
||
" this.root.append(nav_element);\n",
|
||
"\n",
|
||
" // Define a callback function for later on.\n",
|
||
" function toolbar_event(event) {\n",
|
||
" return fig.toolbar_button_onclick(event['data']);\n",
|
||
" }\n",
|
||
" function toolbar_mouse_event(event) {\n",
|
||
" return fig.toolbar_button_onmouseover(event['data']);\n",
|
||
" }\n",
|
||
"\n",
|
||
" for(var toolbar_ind in mpl.toolbar_items) {\n",
|
||
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
|
||
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
|
||
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
|
||
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
|
||
"\n",
|
||
" if (!name) {\n",
|
||
" // put a spacer in here.\n",
|
||
" continue;\n",
|
||
" }\n",
|
||
" var button = $('<button/>');\n",
|
||
" button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
|
||
" 'ui-button-icon-only');\n",
|
||
" button.attr('role', 'button');\n",
|
||
" button.attr('aria-disabled', 'false');\n",
|
||
" button.click(method_name, toolbar_event);\n",
|
||
" button.mouseover(tooltip, toolbar_mouse_event);\n",
|
||
"\n",
|
||
" var icon_img = $('<span/>');\n",
|
||
" icon_img.addClass('ui-button-icon-primary ui-icon');\n",
|
||
" icon_img.addClass(image);\n",
|
||
" icon_img.addClass('ui-corner-all');\n",
|
||
"\n",
|
||
" var tooltip_span = $('<span/>');\n",
|
||
" tooltip_span.addClass('ui-button-text');\n",
|
||
" tooltip_span.html(tooltip);\n",
|
||
"\n",
|
||
" button.append(icon_img);\n",
|
||
" button.append(tooltip_span);\n",
|
||
"\n",
|
||
" nav_element.append(button);\n",
|
||
" }\n",
|
||
"\n",
|
||
" var fmt_picker_span = $('<span/>');\n",
|
||
"\n",
|
||
" var fmt_picker = $('<select/>');\n",
|
||
" fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
|
||
" fmt_picker_span.append(fmt_picker);\n",
|
||
" nav_element.append(fmt_picker_span);\n",
|
||
" this.format_dropdown = fmt_picker[0];\n",
|
||
"\n",
|
||
" for (var ind in mpl.extensions) {\n",
|
||
" var fmt = mpl.extensions[ind];\n",
|
||
" var option = $(\n",
|
||
" '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
|
||
" fmt_picker.append(option)\n",
|
||
" }\n",
|
||
"\n",
|
||
" // Add hover states to the ui-buttons\n",
|
||
" $( \".ui-button\" ).hover(\n",
|
||
" function() { $(this).addClass(\"ui-state-hover\");},\n",
|
||
" function() { $(this).removeClass(\"ui-state-hover\");}\n",
|
||
" );\n",
|
||
"\n",
|
||
" var status_bar = $('<span class=\"mpl-message\"/>');\n",
|
||
" nav_element.append(status_bar);\n",
|
||
" this.message = status_bar[0];\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
|
||
" // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
|
||
" // which will in turn request a refresh of the image.\n",
|
||
" this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.send_message = function(type, properties) {\n",
|
||
" properties['type'] = type;\n",
|
||
" properties['figure_id'] = this.id;\n",
|
||
" this.ws.send(JSON.stringify(properties));\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.send_draw_message = function() {\n",
|
||
" if (!this.waiting) {\n",
|
||
" this.waiting = true;\n",
|
||
" this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
|
||
" }\n",
|
||
"}\n",
|
||
"\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
|
||
" var format_dropdown = fig.format_dropdown;\n",
|
||
" var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
|
||
" fig.ondownload(fig, format);\n",
|
||
"}\n",
|
||
"\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
|
||
" var size = msg['size'];\n",
|
||
" if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
|
||
" fig._resize_canvas(size[0], size[1]);\n",
|
||
" fig.send_message(\"refresh\", {});\n",
|
||
" };\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
|
||
" var x0 = msg['x0'] / mpl.ratio;\n",
|
||
" var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
|
||
" var x1 = msg['x1'] / mpl.ratio;\n",
|
||
" var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
|
||
" x0 = Math.floor(x0) + 0.5;\n",
|
||
" y0 = Math.floor(y0) + 0.5;\n",
|
||
" x1 = Math.floor(x1) + 0.5;\n",
|
||
" y1 = Math.floor(y1) + 0.5;\n",
|
||
" var min_x = Math.min(x0, x1);\n",
|
||
" var min_y = Math.min(y0, y1);\n",
|
||
" var width = Math.abs(x1 - x0);\n",
|
||
" var height = Math.abs(y1 - y0);\n",
|
||
"\n",
|
||
" fig.rubberband_context.clearRect(\n",
|
||
" 0, 0, fig.canvas.width, fig.canvas.height);\n",
|
||
"\n",
|
||
" fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
|
||
" // Updates the figure title.\n",
|
||
" fig.header.textContent = msg['label'];\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
|
||
" var cursor = msg['cursor'];\n",
|
||
" switch(cursor)\n",
|
||
" {\n",
|
||
" case 0:\n",
|
||
" cursor = 'pointer';\n",
|
||
" break;\n",
|
||
" case 1:\n",
|
||
" cursor = 'default';\n",
|
||
" break;\n",
|
||
" case 2:\n",
|
||
" cursor = 'crosshair';\n",
|
||
" break;\n",
|
||
" case 3:\n",
|
||
" cursor = 'move';\n",
|
||
" break;\n",
|
||
" }\n",
|
||
" fig.rubberband_canvas.style.cursor = cursor;\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_message = function(fig, msg) {\n",
|
||
" fig.message.textContent = msg['message'];\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
|
||
" // Request the server to send over a new figure.\n",
|
||
" fig.send_draw_message();\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
|
||
" fig.image_mode = msg['mode'];\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.updated_canvas_event = function() {\n",
|
||
" // Called whenever the canvas gets updated.\n",
|
||
" this.send_message(\"ack\", {});\n",
|
||
"}\n",
|
||
"\n",
|
||
"// A function to construct a web socket function for onmessage handling.\n",
|
||
"// Called in the figure constructor.\n",
|
||
"mpl.figure.prototype._make_on_message_function = function(fig) {\n",
|
||
" return function socket_on_message(evt) {\n",
|
||
" if (evt.data instanceof Blob) {\n",
|
||
" /* FIXME: We get \"Resource interpreted as Image but\n",
|
||
" * transferred with MIME type text/plain:\" errors on\n",
|
||
" * Chrome. But how to set the MIME type? It doesn't seem\n",
|
||
" * to be part of the websocket stream */\n",
|
||
" evt.data.type = \"image/png\";\n",
|
||
"\n",
|
||
" /* Free the memory for the previous frames */\n",
|
||
" if (fig.imageObj.src) {\n",
|
||
" (window.URL || window.webkitURL).revokeObjectURL(\n",
|
||
" fig.imageObj.src);\n",
|
||
" }\n",
|
||
"\n",
|
||
" fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
|
||
" evt.data);\n",
|
||
" fig.updated_canvas_event();\n",
|
||
" fig.waiting = false;\n",
|
||
" return;\n",
|
||
" }\n",
|
||
" else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
|
||
" fig.imageObj.src = evt.data;\n",
|
||
" fig.updated_canvas_event();\n",
|
||
" fig.waiting = false;\n",
|
||
" return;\n",
|
||
" }\n",
|
||
"\n",
|
||
" var msg = JSON.parse(evt.data);\n",
|
||
" var msg_type = msg['type'];\n",
|
||
"\n",
|
||
" // Call the \"handle_{type}\" callback, which takes\n",
|
||
" // the figure and JSON message as its only arguments.\n",
|
||
" try {\n",
|
||
" var callback = fig[\"handle_\" + msg_type];\n",
|
||
" } catch (e) {\n",
|
||
" console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
|
||
" return;\n",
|
||
" }\n",
|
||
"\n",
|
||
" if (callback) {\n",
|
||
" try {\n",
|
||
" // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
|
||
" callback(fig, msg);\n",
|
||
" } catch (e) {\n",
|
||
" console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
|
||
" }\n",
|
||
" }\n",
|
||
" };\n",
|
||
"}\n",
|
||
"\n",
|
||
"// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
|
||
"mpl.findpos = function(e) {\n",
|
||
" //this section is from http://www.quirksmode.org/js/events_properties.html\n",
|
||
" var targ;\n",
|
||
" if (!e)\n",
|
||
" e = window.event;\n",
|
||
" if (e.target)\n",
|
||
" targ = e.target;\n",
|
||
" else if (e.srcElement)\n",
|
||
" targ = e.srcElement;\n",
|
||
" if (targ.nodeType == 3) // defeat Safari bug\n",
|
||
" targ = targ.parentNode;\n",
|
||
"\n",
|
||
" // jQuery normalizes the pageX and pageY\n",
|
||
" // pageX,Y are the mouse positions relative to the document\n",
|
||
" // offset() returns the position of the element relative to the document\n",
|
||
" var x = e.pageX - $(targ).offset().left;\n",
|
||
" var y = e.pageY - $(targ).offset().top;\n",
|
||
"\n",
|
||
" return {\"x\": x, \"y\": y};\n",
|
||
"};\n",
|
||
"\n",
|
||
"/*\n",
|
||
" * return a copy of an object with only non-object keys\n",
|
||
" * we need this to avoid circular references\n",
|
||
" * http://stackoverflow.com/a/24161582/3208463\n",
|
||
" */\n",
|
||
"function simpleKeys (original) {\n",
|
||
" return Object.keys(original).reduce(function (obj, key) {\n",
|
||
" if (typeof original[key] !== 'object')\n",
|
||
" obj[key] = original[key]\n",
|
||
" return obj;\n",
|
||
" }, {});\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.mouse_event = function(event, name) {\n",
|
||
" var canvas_pos = mpl.findpos(event)\n",
|
||
"\n",
|
||
" if (name === 'button_press')\n",
|
||
" {\n",
|
||
" this.canvas.focus();\n",
|
||
" this.canvas_div.focus();\n",
|
||
" }\n",
|
||
"\n",
|
||
" var x = canvas_pos.x * mpl.ratio;\n",
|
||
" var y = canvas_pos.y * mpl.ratio;\n",
|
||
"\n",
|
||
" this.send_message(name, {x: x, y: y, button: event.button,\n",
|
||
" step: event.step,\n",
|
||
" guiEvent: simpleKeys(event)});\n",
|
||
"\n",
|
||
" /* This prevents the web browser from automatically changing to\n",
|
||
" * the text insertion cursor when the button is pressed. We want\n",
|
||
" * to control all of the cursor setting manually through the\n",
|
||
" * 'cursor' event from matplotlib */\n",
|
||
" event.preventDefault();\n",
|
||
" return false;\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
|
||
" // Handle any extra behaviour associated with a key event\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.key_event = function(event, name) {\n",
|
||
"\n",
|
||
" // Prevent repeat events\n",
|
||
" if (name == 'key_press')\n",
|
||
" {\n",
|
||
" if (event.which === this._key)\n",
|
||
" return;\n",
|
||
" else\n",
|
||
" this._key = event.which;\n",
|
||
" }\n",
|
||
" if (name == 'key_release')\n",
|
||
" this._key = null;\n",
|
||
"\n",
|
||
" var value = '';\n",
|
||
" if (event.ctrlKey && event.which != 17)\n",
|
||
" value += \"ctrl+\";\n",
|
||
" if (event.altKey && event.which != 18)\n",
|
||
" value += \"alt+\";\n",
|
||
" if (event.shiftKey && event.which != 16)\n",
|
||
" value += \"shift+\";\n",
|
||
"\n",
|
||
" value += 'k';\n",
|
||
" value += event.which.toString();\n",
|
||
"\n",
|
||
" this._key_event_extra(event, name);\n",
|
||
"\n",
|
||
" this.send_message(name, {key: value,\n",
|
||
" guiEvent: simpleKeys(event)});\n",
|
||
" return false;\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
|
||
" if (name == 'download') {\n",
|
||
" this.handle_save(this, null);\n",
|
||
" } else {\n",
|
||
" this.send_message(\"toolbar_button\", {name: name});\n",
|
||
" }\n",
|
||
"};\n",
|
||
"\n",
|
||
"mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
|
||
" this.message.textContent = tooltip;\n",
|
||
"};\n",
|
||
"mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
|
||
"\n",
|
||
"mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
|
||
"\n",
|
||
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
|
||
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
||
" // object with the appropriate methods. Currently this is a non binary\n",
|
||
" // socket, so there is still some room for performance tuning.\n",
|
||
" var ws = {};\n",
|
||
"\n",
|
||
" ws.close = function() {\n",
|
||
" comm.close()\n",
|
||
" };\n",
|
||
" ws.send = function(m) {\n",
|
||
" //console.log('sending', m);\n",
|
||
" comm.send(m);\n",
|
||
" };\n",
|
||
" // Register the callback with on_msg.\n",
|
||
" comm.on_msg(function(msg) {\n",
|
||
" //console.log('receiving', msg['content']['data'], msg);\n",
|
||
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
|
||
" ws.onmessage(msg['content']['data'])\n",
|
||
" });\n",
|
||
" return ws;\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.mpl_figure_comm = function(comm, msg) {\n",
|
||
" // This is the function which gets called when the mpl process\n",
|
||
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
||
"\n",
|
||
" var id = msg.content.data.id;\n",
|
||
" // Get hold of the div created by the display call when the Comm\n",
|
||
" // socket was opened in Python.\n",
|
||
" var element = $(\"#\" + id);\n",
|
||
" var ws_proxy = comm_websocket_adapter(comm)\n",
|
||
"\n",
|
||
" function ondownload(figure, format) {\n",
|
||
" window.open(figure.imageObj.src);\n",
|
||
" }\n",
|
||
"\n",
|
||
" var fig = new mpl.figure(id, ws_proxy,\n",
|
||
" ondownload,\n",
|
||
" element.get(0));\n",
|
||
"\n",
|
||
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
||
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
||
" ws_proxy.onopen();\n",
|
||
"\n",
|
||
" fig.parent_element = element.get(0);\n",
|
||
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
||
" if (!fig.cell_info) {\n",
|
||
" console.error(\"Failed to find cell for figure\", id, fig);\n",
|
||
" return;\n",
|
||
" }\n",
|
||
"\n",
|
||
" var output_index = fig.cell_info[2]\n",
|
||
" var cell = fig.cell_info[0];\n",
|
||
"\n",
|
||
"};\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
|
||
" var width = fig.canvas.width/mpl.ratio\n",
|
||
" fig.root.unbind('remove')\n",
|
||
"\n",
|
||
" // Update the output cell to use the data from the current canvas.\n",
|
||
" fig.push_to_output();\n",
|
||
" var dataURL = fig.canvas.toDataURL();\n",
|
||
" // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
|
||
" // the notebook keyboard shortcuts fail.\n",
|
||
" IPython.keyboard_manager.enable()\n",
|
||
" $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
|
||
" fig.close_ws(fig, msg);\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.close_ws = function(fig, msg){\n",
|
||
" fig.send_message('closing', msg);\n",
|
||
" // fig.ws.close()\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
|
||
" // Turn the data on the canvas into data in the output cell.\n",
|
||
" var width = this.canvas.width/mpl.ratio\n",
|
||
" var dataURL = this.canvas.toDataURL();\n",
|
||
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.updated_canvas_event = function() {\n",
|
||
" // Tell IPython that the notebook contents must change.\n",
|
||
" IPython.notebook.set_dirty(true);\n",
|
||
" this.send_message(\"ack\", {});\n",
|
||
" var fig = this;\n",
|
||
" // Wait a second, then push the new image to the DOM so\n",
|
||
" // that it is saved nicely (might be nice to debounce this).\n",
|
||
" setTimeout(function () { fig.push_to_output() }, 1000);\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype._init_toolbar = function() {\n",
|
||
" var fig = this;\n",
|
||
"\n",
|
||
" var nav_element = $('<div/>')\n",
|
||
" nav_element.attr('style', 'width: 100%');\n",
|
||
" this.root.append(nav_element);\n",
|
||
"\n",
|
||
" // Define a callback function for later on.\n",
|
||
" function toolbar_event(event) {\n",
|
||
" return fig.toolbar_button_onclick(event['data']);\n",
|
||
" }\n",
|
||
" function toolbar_mouse_event(event) {\n",
|
||
" return fig.toolbar_button_onmouseover(event['data']);\n",
|
||
" }\n",
|
||
"\n",
|
||
" for(var toolbar_ind in mpl.toolbar_items){\n",
|
||
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
|
||
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
|
||
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
|
||
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
|
||
"\n",
|
||
" if (!name) { continue; };\n",
|
||
"\n",
|
||
" var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
|
||
" button.click(method_name, toolbar_event);\n",
|
||
" button.mouseover(tooltip, toolbar_mouse_event);\n",
|
||
" nav_element.append(button);\n",
|
||
" }\n",
|
||
"\n",
|
||
" // Add the status bar.\n",
|
||
" var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
|
||
" nav_element.append(status_bar);\n",
|
||
" this.message = status_bar[0];\n",
|
||
"\n",
|
||
" // Add the close button to the window.\n",
|
||
" var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
|
||
" var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
|
||
" button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
|
||
" button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
|
||
" buttongrp.append(button);\n",
|
||
" var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
|
||
" titlebar.prepend(buttongrp);\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype._root_extra_style = function(el){\n",
|
||
" var fig = this\n",
|
||
" el.on(\"remove\", function(){\n",
|
||
"\tfig.close_ws(fig, {});\n",
|
||
" });\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype._canvas_extra_style = function(el){\n",
|
||
" // this is important to make the div 'focusable\n",
|
||
" el.attr('tabindex', 0)\n",
|
||
" // reach out to IPython and tell the keyboard manager to turn it's self\n",
|
||
" // off when our div gets focus\n",
|
||
"\n",
|
||
" // location in version 3\n",
|
||
" if (IPython.notebook.keyboard_manager) {\n",
|
||
" IPython.notebook.keyboard_manager.register_events(el);\n",
|
||
" }\n",
|
||
" else {\n",
|
||
" // location in version 2\n",
|
||
" IPython.keyboard_manager.register_events(el);\n",
|
||
" }\n",
|
||
"\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
|
||
" var manager = IPython.notebook.keyboard_manager;\n",
|
||
" if (!manager)\n",
|
||
" manager = IPython.keyboard_manager;\n",
|
||
"\n",
|
||
" // Check for shift+enter\n",
|
||
" if (event.shiftKey && event.which == 13) {\n",
|
||
" this.canvas_div.blur();\n",
|
||
" // select the cell after this one\n",
|
||
" var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
|
||
" IPython.notebook.select(index + 1);\n",
|
||
" }\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
|
||
" fig.ondownload(fig, null);\n",
|
||
"}\n",
|
||
"\n",
|
||
"\n",
|
||
"mpl.find_output_cell = function(html_output) {\n",
|
||
" // Return the cell and output element which can be found *uniquely* in the notebook.\n",
|
||
" // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
|
||
" // IPython event is triggered only after the cells have been serialised, which for\n",
|
||
" // our purposes (turning an active figure into a static one), is too late.\n",
|
||
" var cells = IPython.notebook.get_cells();\n",
|
||
" var ncells = cells.length;\n",
|
||
" for (var i=0; i<ncells; i++) {\n",
|
||
" var cell = cells[i];\n",
|
||
" if (cell.cell_type === 'code'){\n",
|
||
" for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
|
||
" var data = cell.output_area.outputs[j];\n",
|
||
" if (data.data) {\n",
|
||
" // IPython >= 3 moved mimebundle to data attribute of output\n",
|
||
" data = data.data;\n",
|
||
" }\n",
|
||
" if (data['text/html'] == html_output) {\n",
|
||
" return [cell, data, j];\n",
|
||
" }\n",
|
||
" }\n",
|
||
" }\n",
|
||
" }\n",
|
||
"}\n",
|
||
"\n",
|
||
"// Register the function which deals with the matplotlib target/channel.\n",
|
||
"// The kernel may be null if the page has been refreshed.\n",
|
||
"if (IPython.notebook.kernel != null) {\n",
|
||
" IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
|
||
"}\n"
|
||
],
|
||
"text/plain": [
|
||
"<IPython.core.display.Javascript object>"
|
||
]
|
||
},
|
||
"metadata": {},
|
||
"output_type": "display_data"
|
||
},
|
||
{
|
||
"data": {
|
||
"text/html": [
|
||
"<img src=\"data:image/png;base64,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\" width=\"640\">"
|
||
],
|
||
"text/plain": [
|
||
"<IPython.core.display.HTML object>"
|
||
]
|
||
},
|
||
"metadata": {},
|
||
"output_type": "display_data"
|
||
}
|
||
],
|
||
"source": [
|
||
"live_plot_rgb_splines(45, 46, 44, spline_s=0.08, max_stdev=1.0, live=False)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 120,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"application/javascript": [
|
||
"/* Put everything inside the global mpl namespace */\n",
|
||
"window.mpl = {};\n",
|
||
"\n",
|
||
"\n",
|
||
"mpl.get_websocket_type = function() {\n",
|
||
" if (typeof(WebSocket) !== 'undefined') {\n",
|
||
" return WebSocket;\n",
|
||
" } else if (typeof(MozWebSocket) !== 'undefined') {\n",
|
||
" return MozWebSocket;\n",
|
||
" } else {\n",
|
||
" alert('Your browser does not have WebSocket support.' +\n",
|
||
" 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
|
||
" 'Firefox 4 and 5 are also supported but you ' +\n",
|
||
" 'have to enable WebSockets in about:config.');\n",
|
||
" };\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
|
||
" this.id = figure_id;\n",
|
||
"\n",
|
||
" this.ws = websocket;\n",
|
||
"\n",
|
||
" this.supports_binary = (this.ws.binaryType != undefined);\n",
|
||
"\n",
|
||
" if (!this.supports_binary) {\n",
|
||
" var warnings = document.getElementById(\"mpl-warnings\");\n",
|
||
" if (warnings) {\n",
|
||
" warnings.style.display = 'block';\n",
|
||
" warnings.textContent = (\n",
|
||
" \"This browser does not support binary websocket messages. \" +\n",
|
||
" \"Performance may be slow.\");\n",
|
||
" }\n",
|
||
" }\n",
|
||
"\n",
|
||
" this.imageObj = new Image();\n",
|
||
"\n",
|
||
" this.context = undefined;\n",
|
||
" this.message = undefined;\n",
|
||
" this.canvas = undefined;\n",
|
||
" this.rubberband_canvas = undefined;\n",
|
||
" this.rubberband_context = undefined;\n",
|
||
" this.format_dropdown = undefined;\n",
|
||
"\n",
|
||
" this.image_mode = 'full';\n",
|
||
"\n",
|
||
" this.root = $('<div/>');\n",
|
||
" this._root_extra_style(this.root)\n",
|
||
" this.root.attr('style', 'display: inline-block');\n",
|
||
"\n",
|
||
" $(parent_element).append(this.root);\n",
|
||
"\n",
|
||
" this._init_header(this);\n",
|
||
" this._init_canvas(this);\n",
|
||
" this._init_toolbar(this);\n",
|
||
"\n",
|
||
" var fig = this;\n",
|
||
"\n",
|
||
" this.waiting = false;\n",
|
||
"\n",
|
||
" this.ws.onopen = function () {\n",
|
||
" fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
|
||
" fig.send_message(\"send_image_mode\", {});\n",
|
||
" if (mpl.ratio != 1) {\n",
|
||
" fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
|
||
" }\n",
|
||
" fig.send_message(\"refresh\", {});\n",
|
||
" }\n",
|
||
"\n",
|
||
" this.imageObj.onload = function() {\n",
|
||
" if (fig.image_mode == 'full') {\n",
|
||
" // Full images could contain transparency (where diff images\n",
|
||
" // almost always do), so we need to clear the canvas so that\n",
|
||
" // there is no ghosting.\n",
|
||
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
||
" }\n",
|
||
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
||
" };\n",
|
||
"\n",
|
||
" this.imageObj.onunload = function() {\n",
|
||
" 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 backingStore = this.context.backingStorePixelRatio ||\n",
|
||
"\tthis.context.webkitBackingStorePixelRatio ||\n",
|
||
"\tthis.context.mozBackingStorePixelRatio ||\n",
|
||
"\tthis.context.msBackingStorePixelRatio ||\n",
|
||
"\tthis.context.oBackingStorePixelRatio ||\n",
|
||
"\tthis.context.backingStorePixelRatio || 1;\n",
|
||
"\n",
|
||
" mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
|
||
"\n",
|
||
" var rubberband = $('<canvas/>');\n",
|
||
" rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
|
||
"\n",
|
||
" var pass_mouse_events = true;\n",
|
||
"\n",
|
||
" canvas_div.resizable({\n",
|
||
" start: function(event, ui) {\n",
|
||
" pass_mouse_events = false;\n",
|
||
" },\n",
|
||
" resize: function(event, ui) {\n",
|
||
" fig.request_resize(ui.size.width, ui.size.height);\n",
|
||
" },\n",
|
||
" stop: function(event, ui) {\n",
|
||
" pass_mouse_events = true;\n",
|
||
" fig.request_resize(ui.size.width, ui.size.height);\n",
|
||
" },\n",
|
||
" });\n",
|
||
"\n",
|
||
" function mouse_event_fn(event) {\n",
|
||
" if (pass_mouse_events)\n",
|
||
" return fig.mouse_event(event, event['data']);\n",
|
||
" }\n",
|
||
"\n",
|
||
" rubberband.mousedown('button_press', mouse_event_fn);\n",
|
||
" rubberband.mouseup('button_release', mouse_event_fn);\n",
|
||
" // Throttle sequential mouse events to 1 every 20ms.\n",
|
||
" rubberband.mousemove('motion_notify', mouse_event_fn);\n",
|
||
"\n",
|
||
" rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
|
||
" rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
|
||
"\n",
|
||
" canvas_div.on(\"wheel\", function (event) {\n",
|
||
" event = event.originalEvent;\n",
|
||
" event['data'] = 'scroll'\n",
|
||
" if (event.deltaY < 0) {\n",
|
||
" event.step = 1;\n",
|
||
" } else {\n",
|
||
" event.step = -1;\n",
|
||
" }\n",
|
||
" mouse_event_fn(event);\n",
|
||
" });\n",
|
||
"\n",
|
||
" canvas_div.append(canvas);\n",
|
||
" canvas_div.append(rubberband);\n",
|
||
"\n",
|
||
" this.rubberband = rubberband;\n",
|
||
" this.rubberband_canvas = rubberband[0];\n",
|
||
" this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
|
||
" this.rubberband_context.strokeStyle = \"#000000\";\n",
|
||
"\n",
|
||
" this._resize_canvas = function(width, height) {\n",
|
||
" // Keep the size of the canvas, canvas container, and rubber band\n",
|
||
" // canvas in synch.\n",
|
||
" canvas_div.css('width', width)\n",
|
||
" canvas_div.css('height', height)\n",
|
||
"\n",
|
||
" canvas.attr('width', width * mpl.ratio);\n",
|
||
" canvas.attr('height', height * mpl.ratio);\n",
|
||
" canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
|
||
"\n",
|
||
" rubberband.attr('width', width);\n",
|
||
" rubberband.attr('height', height);\n",
|
||
" }\n",
|
||
"\n",
|
||
" // Set the figure to an initial 600x600px, this will subsequently be updated\n",
|
||
" // upon first draw.\n",
|
||
" this._resize_canvas(600, 600);\n",
|
||
"\n",
|
||
" // Disable right mouse context menu.\n",
|
||
" $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
|
||
" return false;\n",
|
||
" });\n",
|
||
"\n",
|
||
" function set_focus () {\n",
|
||
" canvas.focus();\n",
|
||
" canvas_div.focus();\n",
|
||
" }\n",
|
||
"\n",
|
||
" window.setTimeout(set_focus, 100);\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype._init_toolbar = function() {\n",
|
||
" var fig = this;\n",
|
||
"\n",
|
||
" var nav_element = $('<div/>')\n",
|
||
" nav_element.attr('style', 'width: 100%');\n",
|
||
" this.root.append(nav_element);\n",
|
||
"\n",
|
||
" // Define a callback function for later on.\n",
|
||
" function toolbar_event(event) {\n",
|
||
" return fig.toolbar_button_onclick(event['data']);\n",
|
||
" }\n",
|
||
" function toolbar_mouse_event(event) {\n",
|
||
" return fig.toolbar_button_onmouseover(event['data']);\n",
|
||
" }\n",
|
||
"\n",
|
||
" for(var toolbar_ind in mpl.toolbar_items) {\n",
|
||
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
|
||
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
|
||
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
|
||
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
|
||
"\n",
|
||
" if (!name) {\n",
|
||
" // put a spacer in here.\n",
|
||
" continue;\n",
|
||
" }\n",
|
||
" var button = $('<button/>');\n",
|
||
" button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
|
||
" 'ui-button-icon-only');\n",
|
||
" button.attr('role', 'button');\n",
|
||
" button.attr('aria-disabled', 'false');\n",
|
||
" button.click(method_name, toolbar_event);\n",
|
||
" button.mouseover(tooltip, toolbar_mouse_event);\n",
|
||
"\n",
|
||
" var icon_img = $('<span/>');\n",
|
||
" icon_img.addClass('ui-button-icon-primary ui-icon');\n",
|
||
" icon_img.addClass(image);\n",
|
||
" icon_img.addClass('ui-corner-all');\n",
|
||
"\n",
|
||
" var tooltip_span = $('<span/>');\n",
|
||
" tooltip_span.addClass('ui-button-text');\n",
|
||
" tooltip_span.html(tooltip);\n",
|
||
"\n",
|
||
" button.append(icon_img);\n",
|
||
" button.append(tooltip_span);\n",
|
||
"\n",
|
||
" nav_element.append(button);\n",
|
||
" }\n",
|
||
"\n",
|
||
" var fmt_picker_span = $('<span/>');\n",
|
||
"\n",
|
||
" var fmt_picker = $('<select/>');\n",
|
||
" fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
|
||
" fmt_picker_span.append(fmt_picker);\n",
|
||
" nav_element.append(fmt_picker_span);\n",
|
||
" this.format_dropdown = fmt_picker[0];\n",
|
||
"\n",
|
||
" for (var ind in mpl.extensions) {\n",
|
||
" var fmt = mpl.extensions[ind];\n",
|
||
" var option = $(\n",
|
||
" '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
|
||
" fmt_picker.append(option)\n",
|
||
" }\n",
|
||
"\n",
|
||
" // Add hover states to the ui-buttons\n",
|
||
" $( \".ui-button\" ).hover(\n",
|
||
" function() { $(this).addClass(\"ui-state-hover\");},\n",
|
||
" function() { $(this).removeClass(\"ui-state-hover\");}\n",
|
||
" );\n",
|
||
"\n",
|
||
" var status_bar = $('<span class=\"mpl-message\"/>');\n",
|
||
" nav_element.append(status_bar);\n",
|
||
" this.message = status_bar[0];\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
|
||
" // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
|
||
" // which will in turn request a refresh of the image.\n",
|
||
" this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.send_message = function(type, properties) {\n",
|
||
" properties['type'] = type;\n",
|
||
" properties['figure_id'] = this.id;\n",
|
||
" this.ws.send(JSON.stringify(properties));\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.send_draw_message = function() {\n",
|
||
" if (!this.waiting) {\n",
|
||
" this.waiting = true;\n",
|
||
" this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
|
||
" }\n",
|
||
"}\n",
|
||
"\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
|
||
" var format_dropdown = fig.format_dropdown;\n",
|
||
" var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
|
||
" fig.ondownload(fig, format);\n",
|
||
"}\n",
|
||
"\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
|
||
" var size = msg['size'];\n",
|
||
" if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
|
||
" fig._resize_canvas(size[0], size[1]);\n",
|
||
" fig.send_message(\"refresh\", {});\n",
|
||
" };\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
|
||
" var x0 = msg['x0'] / mpl.ratio;\n",
|
||
" var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
|
||
" var x1 = msg['x1'] / mpl.ratio;\n",
|
||
" var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
|
||
" x0 = Math.floor(x0) + 0.5;\n",
|
||
" y0 = Math.floor(y0) + 0.5;\n",
|
||
" x1 = Math.floor(x1) + 0.5;\n",
|
||
" y1 = Math.floor(y1) + 0.5;\n",
|
||
" var min_x = Math.min(x0, x1);\n",
|
||
" var min_y = Math.min(y0, y1);\n",
|
||
" var width = Math.abs(x1 - x0);\n",
|
||
" var height = Math.abs(y1 - y0);\n",
|
||
"\n",
|
||
" fig.rubberband_context.clearRect(\n",
|
||
" 0, 0, fig.canvas.width, fig.canvas.height);\n",
|
||
"\n",
|
||
" fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
|
||
" // Updates the figure title.\n",
|
||
" fig.header.textContent = msg['label'];\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
|
||
" var cursor = msg['cursor'];\n",
|
||
" switch(cursor)\n",
|
||
" {\n",
|
||
" case 0:\n",
|
||
" cursor = 'pointer';\n",
|
||
" break;\n",
|
||
" case 1:\n",
|
||
" cursor = 'default';\n",
|
||
" break;\n",
|
||
" case 2:\n",
|
||
" cursor = 'crosshair';\n",
|
||
" break;\n",
|
||
" case 3:\n",
|
||
" cursor = 'move';\n",
|
||
" break;\n",
|
||
" }\n",
|
||
" fig.rubberband_canvas.style.cursor = cursor;\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_message = function(fig, msg) {\n",
|
||
" fig.message.textContent = msg['message'];\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
|
||
" // Request the server to send over a new figure.\n",
|
||
" fig.send_draw_message();\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
|
||
" fig.image_mode = msg['mode'];\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.updated_canvas_event = function() {\n",
|
||
" // Called whenever the canvas gets updated.\n",
|
||
" this.send_message(\"ack\", {});\n",
|
||
"}\n",
|
||
"\n",
|
||
"// A function to construct a web socket function for onmessage handling.\n",
|
||
"// Called in the figure constructor.\n",
|
||
"mpl.figure.prototype._make_on_message_function = function(fig) {\n",
|
||
" return function socket_on_message(evt) {\n",
|
||
" if (evt.data instanceof Blob) {\n",
|
||
" /* FIXME: We get \"Resource interpreted as Image but\n",
|
||
" * transferred with MIME type text/plain:\" errors on\n",
|
||
" * Chrome. But how to set the MIME type? It doesn't seem\n",
|
||
" * to be part of the websocket stream */\n",
|
||
" evt.data.type = \"image/png\";\n",
|
||
"\n",
|
||
" /* Free the memory for the previous frames */\n",
|
||
" if (fig.imageObj.src) {\n",
|
||
" (window.URL || window.webkitURL).revokeObjectURL(\n",
|
||
" fig.imageObj.src);\n",
|
||
" }\n",
|
||
"\n",
|
||
" fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
|
||
" evt.data);\n",
|
||
" fig.updated_canvas_event();\n",
|
||
" fig.waiting = false;\n",
|
||
" return;\n",
|
||
" }\n",
|
||
" else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
|
||
" fig.imageObj.src = evt.data;\n",
|
||
" fig.updated_canvas_event();\n",
|
||
" fig.waiting = false;\n",
|
||
" return;\n",
|
||
" }\n",
|
||
"\n",
|
||
" var msg = JSON.parse(evt.data);\n",
|
||
" var msg_type = msg['type'];\n",
|
||
"\n",
|
||
" // Call the \"handle_{type}\" callback, which takes\n",
|
||
" // the figure and JSON message as its only arguments.\n",
|
||
" try {\n",
|
||
" var callback = fig[\"handle_\" + msg_type];\n",
|
||
" } catch (e) {\n",
|
||
" console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
|
||
" return;\n",
|
||
" }\n",
|
||
"\n",
|
||
" if (callback) {\n",
|
||
" try {\n",
|
||
" // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
|
||
" callback(fig, msg);\n",
|
||
" } catch (e) {\n",
|
||
" console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
|
||
" }\n",
|
||
" }\n",
|
||
" };\n",
|
||
"}\n",
|
||
"\n",
|
||
"// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
|
||
"mpl.findpos = function(e) {\n",
|
||
" //this section is from http://www.quirksmode.org/js/events_properties.html\n",
|
||
" var targ;\n",
|
||
" if (!e)\n",
|
||
" e = window.event;\n",
|
||
" if (e.target)\n",
|
||
" targ = e.target;\n",
|
||
" else if (e.srcElement)\n",
|
||
" targ = e.srcElement;\n",
|
||
" if (targ.nodeType == 3) // defeat Safari bug\n",
|
||
" targ = targ.parentNode;\n",
|
||
"\n",
|
||
" // jQuery normalizes the pageX and pageY\n",
|
||
" // pageX,Y are the mouse positions relative to the document\n",
|
||
" // offset() returns the position of the element relative to the document\n",
|
||
" var x = e.pageX - $(targ).offset().left;\n",
|
||
" var y = e.pageY - $(targ).offset().top;\n",
|
||
"\n",
|
||
" return {\"x\": x, \"y\": y};\n",
|
||
"};\n",
|
||
"\n",
|
||
"/*\n",
|
||
" * return a copy of an object with only non-object keys\n",
|
||
" * we need this to avoid circular references\n",
|
||
" * http://stackoverflow.com/a/24161582/3208463\n",
|
||
" */\n",
|
||
"function simpleKeys (original) {\n",
|
||
" return Object.keys(original).reduce(function (obj, key) {\n",
|
||
" if (typeof original[key] !== 'object')\n",
|
||
" obj[key] = original[key]\n",
|
||
" return obj;\n",
|
||
" }, {});\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.mouse_event = function(event, name) {\n",
|
||
" var canvas_pos = mpl.findpos(event)\n",
|
||
"\n",
|
||
" if (name === 'button_press')\n",
|
||
" {\n",
|
||
" this.canvas.focus();\n",
|
||
" this.canvas_div.focus();\n",
|
||
" }\n",
|
||
"\n",
|
||
" var x = canvas_pos.x * mpl.ratio;\n",
|
||
" var y = canvas_pos.y * mpl.ratio;\n",
|
||
"\n",
|
||
" this.send_message(name, {x: x, y: y, button: event.button,\n",
|
||
" step: event.step,\n",
|
||
" guiEvent: simpleKeys(event)});\n",
|
||
"\n",
|
||
" /* This prevents the web browser from automatically changing to\n",
|
||
" * the text insertion cursor when the button is pressed. We want\n",
|
||
" * to control all of the cursor setting manually through the\n",
|
||
" * 'cursor' event from matplotlib */\n",
|
||
" event.preventDefault();\n",
|
||
" return false;\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
|
||
" // Handle any extra behaviour associated with a key event\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.key_event = function(event, name) {\n",
|
||
"\n",
|
||
" // Prevent repeat events\n",
|
||
" if (name == 'key_press')\n",
|
||
" {\n",
|
||
" if (event.which === this._key)\n",
|
||
" return;\n",
|
||
" else\n",
|
||
" this._key = event.which;\n",
|
||
" }\n",
|
||
" if (name == 'key_release')\n",
|
||
" this._key = null;\n",
|
||
"\n",
|
||
" var value = '';\n",
|
||
" if (event.ctrlKey && event.which != 17)\n",
|
||
" value += \"ctrl+\";\n",
|
||
" if (event.altKey && event.which != 18)\n",
|
||
" value += \"alt+\";\n",
|
||
" if (event.shiftKey && event.which != 16)\n",
|
||
" value += \"shift+\";\n",
|
||
"\n",
|
||
" value += 'k';\n",
|
||
" value += event.which.toString();\n",
|
||
"\n",
|
||
" this._key_event_extra(event, name);\n",
|
||
"\n",
|
||
" this.send_message(name, {key: value,\n",
|
||
" guiEvent: simpleKeys(event)});\n",
|
||
" return false;\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
|
||
" if (name == 'download') {\n",
|
||
" this.handle_save(this, null);\n",
|
||
" } else {\n",
|
||
" this.send_message(\"toolbar_button\", {name: name});\n",
|
||
" }\n",
|
||
"};\n",
|
||
"\n",
|
||
"mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
|
||
" this.message.textContent = tooltip;\n",
|
||
"};\n",
|
||
"mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
|
||
"\n",
|
||
"mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
|
||
"\n",
|
||
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
|
||
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
||
" // object with the appropriate methods. Currently this is a non binary\n",
|
||
" // socket, so there is still some room for performance tuning.\n",
|
||
" var ws = {};\n",
|
||
"\n",
|
||
" ws.close = function() {\n",
|
||
" comm.close()\n",
|
||
" };\n",
|
||
" ws.send = function(m) {\n",
|
||
" //console.log('sending', m);\n",
|
||
" comm.send(m);\n",
|
||
" };\n",
|
||
" // Register the callback with on_msg.\n",
|
||
" comm.on_msg(function(msg) {\n",
|
||
" //console.log('receiving', msg['content']['data'], msg);\n",
|
||
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
|
||
" ws.onmessage(msg['content']['data'])\n",
|
||
" });\n",
|
||
" return ws;\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.mpl_figure_comm = function(comm, msg) {\n",
|
||
" // This is the function which gets called when the mpl process\n",
|
||
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
||
"\n",
|
||
" var id = msg.content.data.id;\n",
|
||
" // Get hold of the div created by the display call when the Comm\n",
|
||
" // socket was opened in Python.\n",
|
||
" var element = $(\"#\" + id);\n",
|
||
" var ws_proxy = comm_websocket_adapter(comm)\n",
|
||
"\n",
|
||
" function ondownload(figure, format) {\n",
|
||
" window.open(figure.imageObj.src);\n",
|
||
" }\n",
|
||
"\n",
|
||
" var fig = new mpl.figure(id, ws_proxy,\n",
|
||
" ondownload,\n",
|
||
" element.get(0));\n",
|
||
"\n",
|
||
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
||
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
||
" ws_proxy.onopen();\n",
|
||
"\n",
|
||
" fig.parent_element = element.get(0);\n",
|
||
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
||
" if (!fig.cell_info) {\n",
|
||
" console.error(\"Failed to find cell for figure\", id, fig);\n",
|
||
" return;\n",
|
||
" }\n",
|
||
"\n",
|
||
" var output_index = fig.cell_info[2]\n",
|
||
" var cell = fig.cell_info[0];\n",
|
||
"\n",
|
||
"};\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
|
||
" var width = fig.canvas.width/mpl.ratio\n",
|
||
" fig.root.unbind('remove')\n",
|
||
"\n",
|
||
" // Update the output cell to use the data from the current canvas.\n",
|
||
" fig.push_to_output();\n",
|
||
" var dataURL = fig.canvas.toDataURL();\n",
|
||
" // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
|
||
" // the notebook keyboard shortcuts fail.\n",
|
||
" IPython.keyboard_manager.enable()\n",
|
||
" $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
|
||
" fig.close_ws(fig, msg);\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.close_ws = function(fig, msg){\n",
|
||
" fig.send_message('closing', msg);\n",
|
||
" // fig.ws.close()\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
|
||
" // Turn the data on the canvas into data in the output cell.\n",
|
||
" var width = this.canvas.width/mpl.ratio\n",
|
||
" var dataURL = this.canvas.toDataURL();\n",
|
||
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.updated_canvas_event = function() {\n",
|
||
" // Tell IPython that the notebook contents must change.\n",
|
||
" IPython.notebook.set_dirty(true);\n",
|
||
" this.send_message(\"ack\", {});\n",
|
||
" var fig = this;\n",
|
||
" // Wait a second, then push the new image to the DOM so\n",
|
||
" // that it is saved nicely (might be nice to debounce this).\n",
|
||
" setTimeout(function () { fig.push_to_output() }, 1000);\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype._init_toolbar = function() {\n",
|
||
" var fig = this;\n",
|
||
"\n",
|
||
" var nav_element = $('<div/>')\n",
|
||
" nav_element.attr('style', 'width: 100%');\n",
|
||
" this.root.append(nav_element);\n",
|
||
"\n",
|
||
" // Define a callback function for later on.\n",
|
||
" function toolbar_event(event) {\n",
|
||
" return fig.toolbar_button_onclick(event['data']);\n",
|
||
" }\n",
|
||
" function toolbar_mouse_event(event) {\n",
|
||
" return fig.toolbar_button_onmouseover(event['data']);\n",
|
||
" }\n",
|
||
"\n",
|
||
" for(var toolbar_ind in mpl.toolbar_items){\n",
|
||
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
|
||
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
|
||
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
|
||
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
|
||
"\n",
|
||
" if (!name) { continue; };\n",
|
||
"\n",
|
||
" var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
|
||
" button.click(method_name, toolbar_event);\n",
|
||
" button.mouseover(tooltip, toolbar_mouse_event);\n",
|
||
" nav_element.append(button);\n",
|
||
" }\n",
|
||
"\n",
|
||
" // Add the status bar.\n",
|
||
" var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
|
||
" nav_element.append(status_bar);\n",
|
||
" this.message = status_bar[0];\n",
|
||
"\n",
|
||
" // Add the close button to the window.\n",
|
||
" var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
|
||
" var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
|
||
" button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
|
||
" button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
|
||
" buttongrp.append(button);\n",
|
||
" var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
|
||
" titlebar.prepend(buttongrp);\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype._root_extra_style = function(el){\n",
|
||
" var fig = this\n",
|
||
" el.on(\"remove\", function(){\n",
|
||
"\tfig.close_ws(fig, {});\n",
|
||
" });\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype._canvas_extra_style = function(el){\n",
|
||
" // this is important to make the div 'focusable\n",
|
||
" el.attr('tabindex', 0)\n",
|
||
" // reach out to IPython and tell the keyboard manager to turn it's self\n",
|
||
" // off when our div gets focus\n",
|
||
"\n",
|
||
" // location in version 3\n",
|
||
" if (IPython.notebook.keyboard_manager) {\n",
|
||
" IPython.notebook.keyboard_manager.register_events(el);\n",
|
||
" }\n",
|
||
" else {\n",
|
||
" // location in version 2\n",
|
||
" IPython.keyboard_manager.register_events(el);\n",
|
||
" }\n",
|
||
"\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
|
||
" var manager = IPython.notebook.keyboard_manager;\n",
|
||
" if (!manager)\n",
|
||
" manager = IPython.keyboard_manager;\n",
|
||
"\n",
|
||
" // Check for shift+enter\n",
|
||
" if (event.shiftKey && event.which == 13) {\n",
|
||
" this.canvas_div.blur();\n",
|
||
" // select the cell after this one\n",
|
||
" var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
|
||
" IPython.notebook.select(index + 1);\n",
|
||
" }\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
|
||
" fig.ondownload(fig, null);\n",
|
||
"}\n",
|
||
"\n",
|
||
"\n",
|
||
"mpl.find_output_cell = function(html_output) {\n",
|
||
" // Return the cell and output element which can be found *uniquely* in the notebook.\n",
|
||
" // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
|
||
" // IPython event is triggered only after the cells have been serialised, which for\n",
|
||
" // our purposes (turning an active figure into a static one), is too late.\n",
|
||
" var cells = IPython.notebook.get_cells();\n",
|
||
" var ncells = cells.length;\n",
|
||
" for (var i=0; i<ncells; i++) {\n",
|
||
" var cell = cells[i];\n",
|
||
" if (cell.cell_type === 'code'){\n",
|
||
" for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
|
||
" var data = cell.output_area.outputs[j];\n",
|
||
" if (data.data) {\n",
|
||
" // IPython >= 3 moved mimebundle to data attribute of output\n",
|
||
" data = data.data;\n",
|
||
" }\n",
|
||
" if (data['text/html'] == html_output) {\n",
|
||
" return [cell, data, j];\n",
|
||
" }\n",
|
||
" }\n",
|
||
" }\n",
|
||
" }\n",
|
||
"}\n",
|
||
"\n",
|
||
"// Register the function which deals with the matplotlib target/channel.\n",
|
||
"// The kernel may be null if the page has been refreshed.\n",
|
||
"if (IPython.notebook.kernel != null) {\n",
|
||
" IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
|
||
"}\n"
|
||
],
|
||
"text/plain": [
|
||
"<IPython.core.display.Javascript object>"
|
||
]
|
||
},
|
||
"metadata": {},
|
||
"output_type": "display_data"
|
||
},
|
||
{
|
||
"data": {
|
||
"text/html": [
|
||
"<img src=\"data:image/png;base64,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\" width=\"640\">"
|
||
],
|
||
"text/plain": [
|
||
"<IPython.core.display.HTML object>"
|
||
]
|
||
},
|
||
"metadata": {},
|
||
"output_type": "display_data"
|
||
}
|
||
],
|
||
"source": [
|
||
"live_plot_rgb_splines(51, 54, 55, 61, spline_s=0.05, max_stdev=1.0, live=False)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 121,
|
||
"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": 122,
|
||
"metadata": {},
|
||
"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",
|
||
"\n",
|
||
"mpl.get_websocket_type = function() {\n",
|
||
" if (typeof(WebSocket) !== 'undefined') {\n",
|
||
" return WebSocket;\n",
|
||
" } else if (typeof(MozWebSocket) !== 'undefined') {\n",
|
||
" return MozWebSocket;\n",
|
||
" } else {\n",
|
||
" alert('Your browser does not have WebSocket support.' +\n",
|
||
" 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
|
||
" 'Firefox 4 and 5 are also supported but you ' +\n",
|
||
" 'have to enable WebSockets in about:config.');\n",
|
||
" };\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
|
||
" this.id = figure_id;\n",
|
||
"\n",
|
||
" this.ws = websocket;\n",
|
||
"\n",
|
||
" this.supports_binary = (this.ws.binaryType != undefined);\n",
|
||
"\n",
|
||
" if (!this.supports_binary) {\n",
|
||
" var warnings = document.getElementById(\"mpl-warnings\");\n",
|
||
" if (warnings) {\n",
|
||
" warnings.style.display = 'block';\n",
|
||
" warnings.textContent = (\n",
|
||
" \"This browser does not support binary websocket messages. \" +\n",
|
||
" \"Performance may be slow.\");\n",
|
||
" }\n",
|
||
" }\n",
|
||
"\n",
|
||
" this.imageObj = new Image();\n",
|
||
"\n",
|
||
" this.context = undefined;\n",
|
||
" this.message = undefined;\n",
|
||
" this.canvas = undefined;\n",
|
||
" this.rubberband_canvas = undefined;\n",
|
||
" this.rubberband_context = undefined;\n",
|
||
" this.format_dropdown = undefined;\n",
|
||
"\n",
|
||
" this.image_mode = 'full';\n",
|
||
"\n",
|
||
" this.root = $('<div/>');\n",
|
||
" this._root_extra_style(this.root)\n",
|
||
" this.root.attr('style', 'display: inline-block');\n",
|
||
"\n",
|
||
" $(parent_element).append(this.root);\n",
|
||
"\n",
|
||
" this._init_header(this);\n",
|
||
" this._init_canvas(this);\n",
|
||
" this._init_toolbar(this);\n",
|
||
"\n",
|
||
" var fig = this;\n",
|
||
"\n",
|
||
" this.waiting = false;\n",
|
||
"\n",
|
||
" this.ws.onopen = function () {\n",
|
||
" fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
|
||
" fig.send_message(\"send_image_mode\", {});\n",
|
||
" if (mpl.ratio != 1) {\n",
|
||
" fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
|
||
" }\n",
|
||
" fig.send_message(\"refresh\", {});\n",
|
||
" }\n",
|
||
"\n",
|
||
" this.imageObj.onload = function() {\n",
|
||
" if (fig.image_mode == 'full') {\n",
|
||
" // Full images could contain transparency (where diff images\n",
|
||
" // almost always do), so we need to clear the canvas so that\n",
|
||
" // there is no ghosting.\n",
|
||
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
||
" }\n",
|
||
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
||
" };\n",
|
||
"\n",
|
||
" this.imageObj.onunload = function() {\n",
|
||
" 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 backingStore = this.context.backingStorePixelRatio ||\n",
|
||
"\tthis.context.webkitBackingStorePixelRatio ||\n",
|
||
"\tthis.context.mozBackingStorePixelRatio ||\n",
|
||
"\tthis.context.msBackingStorePixelRatio ||\n",
|
||
"\tthis.context.oBackingStorePixelRatio ||\n",
|
||
"\tthis.context.backingStorePixelRatio || 1;\n",
|
||
"\n",
|
||
" mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
|
||
"\n",
|
||
" var rubberband = $('<canvas/>');\n",
|
||
" rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
|
||
"\n",
|
||
" var pass_mouse_events = true;\n",
|
||
"\n",
|
||
" canvas_div.resizable({\n",
|
||
" start: function(event, ui) {\n",
|
||
" pass_mouse_events = false;\n",
|
||
" },\n",
|
||
" resize: function(event, ui) {\n",
|
||
" fig.request_resize(ui.size.width, ui.size.height);\n",
|
||
" },\n",
|
||
" stop: function(event, ui) {\n",
|
||
" pass_mouse_events = true;\n",
|
||
" fig.request_resize(ui.size.width, ui.size.height);\n",
|
||
" },\n",
|
||
" });\n",
|
||
"\n",
|
||
" function mouse_event_fn(event) {\n",
|
||
" if (pass_mouse_events)\n",
|
||
" return fig.mouse_event(event, event['data']);\n",
|
||
" }\n",
|
||
"\n",
|
||
" rubberband.mousedown('button_press', mouse_event_fn);\n",
|
||
" rubberband.mouseup('button_release', mouse_event_fn);\n",
|
||
" // Throttle sequential mouse events to 1 every 20ms.\n",
|
||
" rubberband.mousemove('motion_notify', mouse_event_fn);\n",
|
||
"\n",
|
||
" rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
|
||
" rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
|
||
"\n",
|
||
" canvas_div.on(\"wheel\", function (event) {\n",
|
||
" event = event.originalEvent;\n",
|
||
" event['data'] = 'scroll'\n",
|
||
" if (event.deltaY < 0) {\n",
|
||
" event.step = 1;\n",
|
||
" } else {\n",
|
||
" event.step = -1;\n",
|
||
" }\n",
|
||
" mouse_event_fn(event);\n",
|
||
" });\n",
|
||
"\n",
|
||
" canvas_div.append(canvas);\n",
|
||
" canvas_div.append(rubberband);\n",
|
||
"\n",
|
||
" this.rubberband = rubberband;\n",
|
||
" this.rubberband_canvas = rubberband[0];\n",
|
||
" this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
|
||
" this.rubberband_context.strokeStyle = \"#000000\";\n",
|
||
"\n",
|
||
" this._resize_canvas = function(width, height) {\n",
|
||
" // Keep the size of the canvas, canvas container, and rubber band\n",
|
||
" // canvas in synch.\n",
|
||
" canvas_div.css('width', width)\n",
|
||
" canvas_div.css('height', height)\n",
|
||
"\n",
|
||
" canvas.attr('width', width * mpl.ratio);\n",
|
||
" canvas.attr('height', height * mpl.ratio);\n",
|
||
" canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
|
||
"\n",
|
||
" rubberband.attr('width', width);\n",
|
||
" rubberband.attr('height', height);\n",
|
||
" }\n",
|
||
"\n",
|
||
" // Set the figure to an initial 600x600px, this will subsequently be updated\n",
|
||
" // upon first draw.\n",
|
||
" this._resize_canvas(600, 600);\n",
|
||
"\n",
|
||
" // Disable right mouse context menu.\n",
|
||
" $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
|
||
" return false;\n",
|
||
" });\n",
|
||
"\n",
|
||
" function set_focus () {\n",
|
||
" canvas.focus();\n",
|
||
" canvas_div.focus();\n",
|
||
" }\n",
|
||
"\n",
|
||
" window.setTimeout(set_focus, 100);\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype._init_toolbar = function() {\n",
|
||
" var fig = this;\n",
|
||
"\n",
|
||
" var nav_element = $('<div/>')\n",
|
||
" nav_element.attr('style', 'width: 100%');\n",
|
||
" this.root.append(nav_element);\n",
|
||
"\n",
|
||
" // Define a callback function for later on.\n",
|
||
" function toolbar_event(event) {\n",
|
||
" return fig.toolbar_button_onclick(event['data']);\n",
|
||
" }\n",
|
||
" function toolbar_mouse_event(event) {\n",
|
||
" return fig.toolbar_button_onmouseover(event['data']);\n",
|
||
" }\n",
|
||
"\n",
|
||
" for(var toolbar_ind in mpl.toolbar_items) {\n",
|
||
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
|
||
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
|
||
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
|
||
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
|
||
"\n",
|
||
" if (!name) {\n",
|
||
" // put a spacer in here.\n",
|
||
" continue;\n",
|
||
" }\n",
|
||
" var button = $('<button/>');\n",
|
||
" button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
|
||
" 'ui-button-icon-only');\n",
|
||
" button.attr('role', 'button');\n",
|
||
" button.attr('aria-disabled', 'false');\n",
|
||
" button.click(method_name, toolbar_event);\n",
|
||
" button.mouseover(tooltip, toolbar_mouse_event);\n",
|
||
"\n",
|
||
" var icon_img = $('<span/>');\n",
|
||
" icon_img.addClass('ui-button-icon-primary ui-icon');\n",
|
||
" icon_img.addClass(image);\n",
|
||
" icon_img.addClass('ui-corner-all');\n",
|
||
"\n",
|
||
" var tooltip_span = $('<span/>');\n",
|
||
" tooltip_span.addClass('ui-button-text');\n",
|
||
" tooltip_span.html(tooltip);\n",
|
||
"\n",
|
||
" button.append(icon_img);\n",
|
||
" button.append(tooltip_span);\n",
|
||
"\n",
|
||
" nav_element.append(button);\n",
|
||
" }\n",
|
||
"\n",
|
||
" var fmt_picker_span = $('<span/>');\n",
|
||
"\n",
|
||
" var fmt_picker = $('<select/>');\n",
|
||
" fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
|
||
" fmt_picker_span.append(fmt_picker);\n",
|
||
" nav_element.append(fmt_picker_span);\n",
|
||
" this.format_dropdown = fmt_picker[0];\n",
|
||
"\n",
|
||
" for (var ind in mpl.extensions) {\n",
|
||
" var fmt = mpl.extensions[ind];\n",
|
||
" var option = $(\n",
|
||
" '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
|
||
" fmt_picker.append(option)\n",
|
||
" }\n",
|
||
"\n",
|
||
" // Add hover states to the ui-buttons\n",
|
||
" $( \".ui-button\" ).hover(\n",
|
||
" function() { $(this).addClass(\"ui-state-hover\");},\n",
|
||
" function() { $(this).removeClass(\"ui-state-hover\");}\n",
|
||
" );\n",
|
||
"\n",
|
||
" var status_bar = $('<span class=\"mpl-message\"/>');\n",
|
||
" nav_element.append(status_bar);\n",
|
||
" this.message = status_bar[0];\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
|
||
" // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
|
||
" // which will in turn request a refresh of the image.\n",
|
||
" this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.send_message = function(type, properties) {\n",
|
||
" properties['type'] = type;\n",
|
||
" properties['figure_id'] = this.id;\n",
|
||
" this.ws.send(JSON.stringify(properties));\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.send_draw_message = function() {\n",
|
||
" if (!this.waiting) {\n",
|
||
" this.waiting = true;\n",
|
||
" this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
|
||
" }\n",
|
||
"}\n",
|
||
"\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
|
||
" var format_dropdown = fig.format_dropdown;\n",
|
||
" var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
|
||
" fig.ondownload(fig, format);\n",
|
||
"}\n",
|
||
"\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
|
||
" var size = msg['size'];\n",
|
||
" if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
|
||
" fig._resize_canvas(size[0], size[1]);\n",
|
||
" fig.send_message(\"refresh\", {});\n",
|
||
" };\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
|
||
" var x0 = msg['x0'] / mpl.ratio;\n",
|
||
" var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
|
||
" var x1 = msg['x1'] / mpl.ratio;\n",
|
||
" var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
|
||
" x0 = Math.floor(x0) + 0.5;\n",
|
||
" y0 = Math.floor(y0) + 0.5;\n",
|
||
" x1 = Math.floor(x1) + 0.5;\n",
|
||
" y1 = Math.floor(y1) + 0.5;\n",
|
||
" var min_x = Math.min(x0, x1);\n",
|
||
" var min_y = Math.min(y0, y1);\n",
|
||
" var width = Math.abs(x1 - x0);\n",
|
||
" var height = Math.abs(y1 - y0);\n",
|
||
"\n",
|
||
" fig.rubberband_context.clearRect(\n",
|
||
" 0, 0, fig.canvas.width, fig.canvas.height);\n",
|
||
"\n",
|
||
" fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
|
||
" // Updates the figure title.\n",
|
||
" fig.header.textContent = msg['label'];\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
|
||
" var cursor = msg['cursor'];\n",
|
||
" switch(cursor)\n",
|
||
" {\n",
|
||
" case 0:\n",
|
||
" cursor = 'pointer';\n",
|
||
" break;\n",
|
||
" case 1:\n",
|
||
" cursor = 'default';\n",
|
||
" break;\n",
|
||
" case 2:\n",
|
||
" cursor = 'crosshair';\n",
|
||
" break;\n",
|
||
" case 3:\n",
|
||
" cursor = 'move';\n",
|
||
" break;\n",
|
||
" }\n",
|
||
" fig.rubberband_canvas.style.cursor = cursor;\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_message = function(fig, msg) {\n",
|
||
" fig.message.textContent = msg['message'];\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
|
||
" // Request the server to send over a new figure.\n",
|
||
" fig.send_draw_message();\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
|
||
" fig.image_mode = msg['mode'];\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.updated_canvas_event = function() {\n",
|
||
" // Called whenever the canvas gets updated.\n",
|
||
" this.send_message(\"ack\", {});\n",
|
||
"}\n",
|
||
"\n",
|
||
"// A function to construct a web socket function for onmessage handling.\n",
|
||
"// Called in the figure constructor.\n",
|
||
"mpl.figure.prototype._make_on_message_function = function(fig) {\n",
|
||
" return function socket_on_message(evt) {\n",
|
||
" if (evt.data instanceof Blob) {\n",
|
||
" /* FIXME: We get \"Resource interpreted as Image but\n",
|
||
" * transferred with MIME type text/plain:\" errors on\n",
|
||
" * Chrome. But how to set the MIME type? It doesn't seem\n",
|
||
" * to be part of the websocket stream */\n",
|
||
" evt.data.type = \"image/png\";\n",
|
||
"\n",
|
||
" /* Free the memory for the previous frames */\n",
|
||
" if (fig.imageObj.src) {\n",
|
||
" (window.URL || window.webkitURL).revokeObjectURL(\n",
|
||
" fig.imageObj.src);\n",
|
||
" }\n",
|
||
"\n",
|
||
" fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
|
||
" evt.data);\n",
|
||
" fig.updated_canvas_event();\n",
|
||
" fig.waiting = false;\n",
|
||
" return;\n",
|
||
" }\n",
|
||
" else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
|
||
" fig.imageObj.src = evt.data;\n",
|
||
" fig.updated_canvas_event();\n",
|
||
" fig.waiting = false;\n",
|
||
" return;\n",
|
||
" }\n",
|
||
"\n",
|
||
" var msg = JSON.parse(evt.data);\n",
|
||
" var msg_type = msg['type'];\n",
|
||
"\n",
|
||
" // Call the \"handle_{type}\" callback, which takes\n",
|
||
" // the figure and JSON message as its only arguments.\n",
|
||
" try {\n",
|
||
" var callback = fig[\"handle_\" + msg_type];\n",
|
||
" } catch (e) {\n",
|
||
" console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
|
||
" return;\n",
|
||
" }\n",
|
||
"\n",
|
||
" if (callback) {\n",
|
||
" try {\n",
|
||
" // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
|
||
" callback(fig, msg);\n",
|
||
" } catch (e) {\n",
|
||
" console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
|
||
" }\n",
|
||
" }\n",
|
||
" };\n",
|
||
"}\n",
|
||
"\n",
|
||
"// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
|
||
"mpl.findpos = function(e) {\n",
|
||
" //this section is from http://www.quirksmode.org/js/events_properties.html\n",
|
||
" var targ;\n",
|
||
" if (!e)\n",
|
||
" e = window.event;\n",
|
||
" if (e.target)\n",
|
||
" targ = e.target;\n",
|
||
" else if (e.srcElement)\n",
|
||
" targ = e.srcElement;\n",
|
||
" if (targ.nodeType == 3) // defeat Safari bug\n",
|
||
" targ = targ.parentNode;\n",
|
||
"\n",
|
||
" // jQuery normalizes the pageX and pageY\n",
|
||
" // pageX,Y are the mouse positions relative to the document\n",
|
||
" // offset() returns the position of the element relative to the document\n",
|
||
" var x = e.pageX - $(targ).offset().left;\n",
|
||
" var y = e.pageY - $(targ).offset().top;\n",
|
||
"\n",
|
||
" return {\"x\": x, \"y\": y};\n",
|
||
"};\n",
|
||
"\n",
|
||
"/*\n",
|
||
" * return a copy of an object with only non-object keys\n",
|
||
" * we need this to avoid circular references\n",
|
||
" * http://stackoverflow.com/a/24161582/3208463\n",
|
||
" */\n",
|
||
"function simpleKeys (original) {\n",
|
||
" return Object.keys(original).reduce(function (obj, key) {\n",
|
||
" if (typeof original[key] !== 'object')\n",
|
||
" obj[key] = original[key]\n",
|
||
" return obj;\n",
|
||
" }, {});\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.mouse_event = function(event, name) {\n",
|
||
" var canvas_pos = mpl.findpos(event)\n",
|
||
"\n",
|
||
" if (name === 'button_press')\n",
|
||
" {\n",
|
||
" this.canvas.focus();\n",
|
||
" this.canvas_div.focus();\n",
|
||
" }\n",
|
||
"\n",
|
||
" var x = canvas_pos.x * mpl.ratio;\n",
|
||
" var y = canvas_pos.y * mpl.ratio;\n",
|
||
"\n",
|
||
" this.send_message(name, {x: x, y: y, button: event.button,\n",
|
||
" step: event.step,\n",
|
||
" guiEvent: simpleKeys(event)});\n",
|
||
"\n",
|
||
" /* This prevents the web browser from automatically changing to\n",
|
||
" * the text insertion cursor when the button is pressed. We want\n",
|
||
" * to control all of the cursor setting manually through the\n",
|
||
" * 'cursor' event from matplotlib */\n",
|
||
" event.preventDefault();\n",
|
||
" return false;\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
|
||
" // Handle any extra behaviour associated with a key event\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.key_event = function(event, name) {\n",
|
||
"\n",
|
||
" // Prevent repeat events\n",
|
||
" if (name == 'key_press')\n",
|
||
" {\n",
|
||
" if (event.which === this._key)\n",
|
||
" return;\n",
|
||
" else\n",
|
||
" this._key = event.which;\n",
|
||
" }\n",
|
||
" if (name == 'key_release')\n",
|
||
" this._key = null;\n",
|
||
"\n",
|
||
" var value = '';\n",
|
||
" if (event.ctrlKey && event.which != 17)\n",
|
||
" value += \"ctrl+\";\n",
|
||
" if (event.altKey && event.which != 18)\n",
|
||
" value += \"alt+\";\n",
|
||
" if (event.shiftKey && event.which != 16)\n",
|
||
" value += \"shift+\";\n",
|
||
"\n",
|
||
" value += 'k';\n",
|
||
" value += event.which.toString();\n",
|
||
"\n",
|
||
" this._key_event_extra(event, name);\n",
|
||
"\n",
|
||
" this.send_message(name, {key: value,\n",
|
||
" guiEvent: simpleKeys(event)});\n",
|
||
" return false;\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
|
||
" if (name == 'download') {\n",
|
||
" this.handle_save(this, null);\n",
|
||
" } else {\n",
|
||
" this.send_message(\"toolbar_button\", {name: name});\n",
|
||
" }\n",
|
||
"};\n",
|
||
"\n",
|
||
"mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
|
||
" this.message.textContent = tooltip;\n",
|
||
"};\n",
|
||
"mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
|
||
"\n",
|
||
"mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
|
||
"\n",
|
||
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
|
||
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
||
" // object with the appropriate methods. Currently this is a non binary\n",
|
||
" // socket, so there is still some room for performance tuning.\n",
|
||
" var ws = {};\n",
|
||
"\n",
|
||
" ws.close = function() {\n",
|
||
" comm.close()\n",
|
||
" };\n",
|
||
" ws.send = function(m) {\n",
|
||
" //console.log('sending', m);\n",
|
||
" comm.send(m);\n",
|
||
" };\n",
|
||
" // Register the callback with on_msg.\n",
|
||
" comm.on_msg(function(msg) {\n",
|
||
" //console.log('receiving', msg['content']['data'], msg);\n",
|
||
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
|
||
" ws.onmessage(msg['content']['data'])\n",
|
||
" });\n",
|
||
" return ws;\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.mpl_figure_comm = function(comm, msg) {\n",
|
||
" // This is the function which gets called when the mpl process\n",
|
||
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
||
"\n",
|
||
" var id = msg.content.data.id;\n",
|
||
" // Get hold of the div created by the display call when the Comm\n",
|
||
" // socket was opened in Python.\n",
|
||
" var element = $(\"#\" + id);\n",
|
||
" var ws_proxy = comm_websocket_adapter(comm)\n",
|
||
"\n",
|
||
" function ondownload(figure, format) {\n",
|
||
" window.open(figure.imageObj.src);\n",
|
||
" }\n",
|
||
"\n",
|
||
" var fig = new mpl.figure(id, ws_proxy,\n",
|
||
" ondownload,\n",
|
||
" element.get(0));\n",
|
||
"\n",
|
||
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
||
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
||
" ws_proxy.onopen();\n",
|
||
"\n",
|
||
" fig.parent_element = element.get(0);\n",
|
||
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
||
" if (!fig.cell_info) {\n",
|
||
" console.error(\"Failed to find cell for figure\", id, fig);\n",
|
||
" return;\n",
|
||
" }\n",
|
||
"\n",
|
||
" var output_index = fig.cell_info[2]\n",
|
||
" var cell = fig.cell_info[0];\n",
|
||
"\n",
|
||
"};\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
|
||
" var width = fig.canvas.width/mpl.ratio\n",
|
||
" fig.root.unbind('remove')\n",
|
||
"\n",
|
||
" // Update the output cell to use the data from the current canvas.\n",
|
||
" fig.push_to_output();\n",
|
||
" var dataURL = fig.canvas.toDataURL();\n",
|
||
" // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
|
||
" // the notebook keyboard shortcuts fail.\n",
|
||
" IPython.keyboard_manager.enable()\n",
|
||
" $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
|
||
" fig.close_ws(fig, msg);\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.close_ws = function(fig, msg){\n",
|
||
" fig.send_message('closing', msg);\n",
|
||
" // fig.ws.close()\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
|
||
" // Turn the data on the canvas into data in the output cell.\n",
|
||
" var width = this.canvas.width/mpl.ratio\n",
|
||
" var dataURL = this.canvas.toDataURL();\n",
|
||
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.updated_canvas_event = function() {\n",
|
||
" // Tell IPython that the notebook contents must change.\n",
|
||
" IPython.notebook.set_dirty(true);\n",
|
||
" this.send_message(\"ack\", {});\n",
|
||
" var fig = this;\n",
|
||
" // Wait a second, then push the new image to the DOM so\n",
|
||
" // that it is saved nicely (might be nice to debounce this).\n",
|
||
" setTimeout(function () { fig.push_to_output() }, 1000);\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype._init_toolbar = function() {\n",
|
||
" var fig = this;\n",
|
||
"\n",
|
||
" var nav_element = $('<div/>')\n",
|
||
" nav_element.attr('style', 'width: 100%');\n",
|
||
" this.root.append(nav_element);\n",
|
||
"\n",
|
||
" // Define a callback function for later on.\n",
|
||
" function toolbar_event(event) {\n",
|
||
" return fig.toolbar_button_onclick(event['data']);\n",
|
||
" }\n",
|
||
" function toolbar_mouse_event(event) {\n",
|
||
" return fig.toolbar_button_onmouseover(event['data']);\n",
|
||
" }\n",
|
||
"\n",
|
||
" for(var toolbar_ind in mpl.toolbar_items){\n",
|
||
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
|
||
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
|
||
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
|
||
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
|
||
"\n",
|
||
" if (!name) { continue; };\n",
|
||
"\n",
|
||
" var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
|
||
" button.click(method_name, toolbar_event);\n",
|
||
" button.mouseover(tooltip, toolbar_mouse_event);\n",
|
||
" nav_element.append(button);\n",
|
||
" }\n",
|
||
"\n",
|
||
" // Add the status bar.\n",
|
||
" var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
|
||
" nav_element.append(status_bar);\n",
|
||
" this.message = status_bar[0];\n",
|
||
"\n",
|
||
" // Add the close button to the window.\n",
|
||
" var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
|
||
" var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
|
||
" button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
|
||
" button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
|
||
" buttongrp.append(button);\n",
|
||
" var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
|
||
" titlebar.prepend(buttongrp);\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype._root_extra_style = function(el){\n",
|
||
" var fig = this\n",
|
||
" el.on(\"remove\", function(){\n",
|
||
"\tfig.close_ws(fig, {});\n",
|
||
" });\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype._canvas_extra_style = function(el){\n",
|
||
" // this is important to make the div 'focusable\n",
|
||
" el.attr('tabindex', 0)\n",
|
||
" // reach out to IPython and tell the keyboard manager to turn it's self\n",
|
||
" // off when our div gets focus\n",
|
||
"\n",
|
||
" // location in version 3\n",
|
||
" if (IPython.notebook.keyboard_manager) {\n",
|
||
" IPython.notebook.keyboard_manager.register_events(el);\n",
|
||
" }\n",
|
||
" else {\n",
|
||
" // location in version 2\n",
|
||
" IPython.keyboard_manager.register_events(el);\n",
|
||
" }\n",
|
||
"\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
|
||
" var manager = IPython.notebook.keyboard_manager;\n",
|
||
" if (!manager)\n",
|
||
" manager = IPython.keyboard_manager;\n",
|
||
"\n",
|
||
" // Check for shift+enter\n",
|
||
" if (event.shiftKey && event.which == 13) {\n",
|
||
" this.canvas_div.blur();\n",
|
||
" // select the cell after this one\n",
|
||
" var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
|
||
" IPython.notebook.select(index + 1);\n",
|
||
" }\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
|
||
" fig.ondownload(fig, null);\n",
|
||
"}\n",
|
||
"\n",
|
||
"\n",
|
||
"mpl.find_output_cell = function(html_output) {\n",
|
||
" // Return the cell and output element which can be found *uniquely* in the notebook.\n",
|
||
" // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
|
||
" // IPython event is triggered only after the cells have been serialised, which for\n",
|
||
" // our purposes (turning an active figure into a static one), is too late.\n",
|
||
" var cells = IPython.notebook.get_cells();\n",
|
||
" var ncells = cells.length;\n",
|
||
" for (var i=0; i<ncells; i++) {\n",
|
||
" var cell = cells[i];\n",
|
||
" if (cell.cell_type === 'code'){\n",
|
||
" for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
|
||
" var data = cell.output_area.outputs[j];\n",
|
||
" if (data.data) {\n",
|
||
" // IPython >= 3 moved mimebundle to data attribute of output\n",
|
||
" data = data.data;\n",
|
||
" }\n",
|
||
" if (data['text/html'] == html_output) {\n",
|
||
" return [cell, data, j];\n",
|
||
" }\n",
|
||
" }\n",
|
||
" }\n",
|
||
" }\n",
|
||
"}\n",
|
||
"\n",
|
||
"// Register the function which deals with the matplotlib target/channel.\n",
|
||
"// The kernel may be null if the page has been refreshed.\n",
|
||
"if (IPython.notebook.kernel != null) {\n",
|
||
" IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
|
||
"}\n"
|
||
],
|
||
"text/plain": [
|
||
"<IPython.core.display.Javascript object>"
|
||
]
|
||
},
|
||
"metadata": {},
|
||
"output_type": "display_data"
|
||
},
|
||
{
|
||
"data": {
|
||
"text/html": [
|
||
"<img src=\"data:image/png;base64,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\" width=\"640\">"
|
||
],
|
||
"text/plain": [
|
||
"<IPython.core.display.HTML object>"
|
||
]
|
||
},
|
||
"metadata": {},
|
||
"output_type": "display_data"
|
||
}
|
||
],
|
||
"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": 166,
|
||
"metadata": {
|
||
"collapsed": true
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"def plot_rgb_bar(data_rgb, ids_rgb, spline_s=1, show_label=True, save_svg=None):\n",
|
||
" fig, ax = plt.subplots(1, 1)\n",
|
||
" if show_label:\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",
|
||
" colors = [\n",
|
||
" (('#fe3ea0', '#ffd2e9')) #ff99cc\n",
|
||
" ] * 4\n",
|
||
" print('spline_s', spline_s)\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, zorder=1)\n",
|
||
" \n",
|
||
" spline = inter.UnivariateSpline(steps, values, s=spline_s)\n",
|
||
" ax.plot(steps, spline(steps), color=color_dark, zorder=2)\n",
|
||
" \n",
|
||
" ax.spines['top'].set_visible(False)\n",
|
||
" ax.spines['right'].set_visible(False)\n",
|
||
" ax.spines['bottom'].set_color('#08bdf9')\n",
|
||
" ax.spines['left'].set_color('#08bdf9')\n",
|
||
" ax.tick_params(axis='x', colors='#01769D')\n",
|
||
" ax.tick_params(axis='y', colors='#01769D')\n",
|
||
" ax.xaxis.label.set_color('#01769D')\n",
|
||
" ax.yaxis.label.set_color('#01769D')\n",
|
||
" ax.grid(color='#08bdf9', linestyle=':')\n",
|
||
" \n",
|
||
" ax.set_xlim([380, 720])\n",
|
||
" ax.set_xlabel('$\\lambda\\;[nm]$')\n",
|
||
" ax.set_ylabel('$I_{pd}\\;[nA]$')\n",
|
||
" \n",
|
||
" if save_svg:\n",
|
||
" fig.savefig(save_svg)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 124,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"application/javascript": [
|
||
"/* Put everything inside the global mpl namespace */\n",
|
||
"window.mpl = {};\n",
|
||
"\n",
|
||
"\n",
|
||
"mpl.get_websocket_type = function() {\n",
|
||
" if (typeof(WebSocket) !== 'undefined') {\n",
|
||
" return WebSocket;\n",
|
||
" } else if (typeof(MozWebSocket) !== 'undefined') {\n",
|
||
" return MozWebSocket;\n",
|
||
" } else {\n",
|
||
" alert('Your browser does not have WebSocket support.' +\n",
|
||
" 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
|
||
" 'Firefox 4 and 5 are also supported but you ' +\n",
|
||
" 'have to enable WebSockets in about:config.');\n",
|
||
" };\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
|
||
" this.id = figure_id;\n",
|
||
"\n",
|
||
" this.ws = websocket;\n",
|
||
"\n",
|
||
" this.supports_binary = (this.ws.binaryType != undefined);\n",
|
||
"\n",
|
||
" if (!this.supports_binary) {\n",
|
||
" var warnings = document.getElementById(\"mpl-warnings\");\n",
|
||
" if (warnings) {\n",
|
||
" warnings.style.display = 'block';\n",
|
||
" warnings.textContent = (\n",
|
||
" \"This browser does not support binary websocket messages. \" +\n",
|
||
" \"Performance may be slow.\");\n",
|
||
" }\n",
|
||
" }\n",
|
||
"\n",
|
||
" this.imageObj = new Image();\n",
|
||
"\n",
|
||
" this.context = undefined;\n",
|
||
" this.message = undefined;\n",
|
||
" this.canvas = undefined;\n",
|
||
" this.rubberband_canvas = undefined;\n",
|
||
" this.rubberband_context = undefined;\n",
|
||
" this.format_dropdown = undefined;\n",
|
||
"\n",
|
||
" this.image_mode = 'full';\n",
|
||
"\n",
|
||
" this.root = $('<div/>');\n",
|
||
" this._root_extra_style(this.root)\n",
|
||
" this.root.attr('style', 'display: inline-block');\n",
|
||
"\n",
|
||
" $(parent_element).append(this.root);\n",
|
||
"\n",
|
||
" this._init_header(this);\n",
|
||
" this._init_canvas(this);\n",
|
||
" this._init_toolbar(this);\n",
|
||
"\n",
|
||
" var fig = this;\n",
|
||
"\n",
|
||
" this.waiting = false;\n",
|
||
"\n",
|
||
" this.ws.onopen = function () {\n",
|
||
" fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
|
||
" fig.send_message(\"send_image_mode\", {});\n",
|
||
" if (mpl.ratio != 1) {\n",
|
||
" fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
|
||
" }\n",
|
||
" fig.send_message(\"refresh\", {});\n",
|
||
" }\n",
|
||
"\n",
|
||
" this.imageObj.onload = function() {\n",
|
||
" if (fig.image_mode == 'full') {\n",
|
||
" // Full images could contain transparency (where diff images\n",
|
||
" // almost always do), so we need to clear the canvas so that\n",
|
||
" // there is no ghosting.\n",
|
||
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
||
" }\n",
|
||
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
||
" };\n",
|
||
"\n",
|
||
" this.imageObj.onunload = function() {\n",
|
||
" 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 backingStore = this.context.backingStorePixelRatio ||\n",
|
||
"\tthis.context.webkitBackingStorePixelRatio ||\n",
|
||
"\tthis.context.mozBackingStorePixelRatio ||\n",
|
||
"\tthis.context.msBackingStorePixelRatio ||\n",
|
||
"\tthis.context.oBackingStorePixelRatio ||\n",
|
||
"\tthis.context.backingStorePixelRatio || 1;\n",
|
||
"\n",
|
||
" mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
|
||
"\n",
|
||
" var rubberband = $('<canvas/>');\n",
|
||
" rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
|
||
"\n",
|
||
" var pass_mouse_events = true;\n",
|
||
"\n",
|
||
" canvas_div.resizable({\n",
|
||
" start: function(event, ui) {\n",
|
||
" pass_mouse_events = false;\n",
|
||
" },\n",
|
||
" resize: function(event, ui) {\n",
|
||
" fig.request_resize(ui.size.width, ui.size.height);\n",
|
||
" },\n",
|
||
" stop: function(event, ui) {\n",
|
||
" pass_mouse_events = true;\n",
|
||
" fig.request_resize(ui.size.width, ui.size.height);\n",
|
||
" },\n",
|
||
" });\n",
|
||
"\n",
|
||
" function mouse_event_fn(event) {\n",
|
||
" if (pass_mouse_events)\n",
|
||
" return fig.mouse_event(event, event['data']);\n",
|
||
" }\n",
|
||
"\n",
|
||
" rubberband.mousedown('button_press', mouse_event_fn);\n",
|
||
" rubberband.mouseup('button_release', mouse_event_fn);\n",
|
||
" // Throttle sequential mouse events to 1 every 20ms.\n",
|
||
" rubberband.mousemove('motion_notify', mouse_event_fn);\n",
|
||
"\n",
|
||
" rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
|
||
" rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
|
||
"\n",
|
||
" canvas_div.on(\"wheel\", function (event) {\n",
|
||
" event = event.originalEvent;\n",
|
||
" event['data'] = 'scroll'\n",
|
||
" if (event.deltaY < 0) {\n",
|
||
" event.step = 1;\n",
|
||
" } else {\n",
|
||
" event.step = -1;\n",
|
||
" }\n",
|
||
" mouse_event_fn(event);\n",
|
||
" });\n",
|
||
"\n",
|
||
" canvas_div.append(canvas);\n",
|
||
" canvas_div.append(rubberband);\n",
|
||
"\n",
|
||
" this.rubberband = rubberband;\n",
|
||
" this.rubberband_canvas = rubberband[0];\n",
|
||
" this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
|
||
" this.rubberband_context.strokeStyle = \"#000000\";\n",
|
||
"\n",
|
||
" this._resize_canvas = function(width, height) {\n",
|
||
" // Keep the size of the canvas, canvas container, and rubber band\n",
|
||
" // canvas in synch.\n",
|
||
" canvas_div.css('width', width)\n",
|
||
" canvas_div.css('height', height)\n",
|
||
"\n",
|
||
" canvas.attr('width', width * mpl.ratio);\n",
|
||
" canvas.attr('height', height * mpl.ratio);\n",
|
||
" canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
|
||
"\n",
|
||
" rubberband.attr('width', width);\n",
|
||
" rubberband.attr('height', height);\n",
|
||
" }\n",
|
||
"\n",
|
||
" // Set the figure to an initial 600x600px, this will subsequently be updated\n",
|
||
" // upon first draw.\n",
|
||
" this._resize_canvas(600, 600);\n",
|
||
"\n",
|
||
" // Disable right mouse context menu.\n",
|
||
" $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
|
||
" return false;\n",
|
||
" });\n",
|
||
"\n",
|
||
" function set_focus () {\n",
|
||
" canvas.focus();\n",
|
||
" canvas_div.focus();\n",
|
||
" }\n",
|
||
"\n",
|
||
" window.setTimeout(set_focus, 100);\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype._init_toolbar = function() {\n",
|
||
" var fig = this;\n",
|
||
"\n",
|
||
" var nav_element = $('<div/>')\n",
|
||
" nav_element.attr('style', 'width: 100%');\n",
|
||
" this.root.append(nav_element);\n",
|
||
"\n",
|
||
" // Define a callback function for later on.\n",
|
||
" function toolbar_event(event) {\n",
|
||
" return fig.toolbar_button_onclick(event['data']);\n",
|
||
" }\n",
|
||
" function toolbar_mouse_event(event) {\n",
|
||
" return fig.toolbar_button_onmouseover(event['data']);\n",
|
||
" }\n",
|
||
"\n",
|
||
" for(var toolbar_ind in mpl.toolbar_items) {\n",
|
||
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
|
||
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
|
||
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
|
||
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
|
||
"\n",
|
||
" if (!name) {\n",
|
||
" // put a spacer in here.\n",
|
||
" continue;\n",
|
||
" }\n",
|
||
" var button = $('<button/>');\n",
|
||
" button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
|
||
" 'ui-button-icon-only');\n",
|
||
" button.attr('role', 'button');\n",
|
||
" button.attr('aria-disabled', 'false');\n",
|
||
" button.click(method_name, toolbar_event);\n",
|
||
" button.mouseover(tooltip, toolbar_mouse_event);\n",
|
||
"\n",
|
||
" var icon_img = $('<span/>');\n",
|
||
" icon_img.addClass('ui-button-icon-primary ui-icon');\n",
|
||
" icon_img.addClass(image);\n",
|
||
" icon_img.addClass('ui-corner-all');\n",
|
||
"\n",
|
||
" var tooltip_span = $('<span/>');\n",
|
||
" tooltip_span.addClass('ui-button-text');\n",
|
||
" tooltip_span.html(tooltip);\n",
|
||
"\n",
|
||
" button.append(icon_img);\n",
|
||
" button.append(tooltip_span);\n",
|
||
"\n",
|
||
" nav_element.append(button);\n",
|
||
" }\n",
|
||
"\n",
|
||
" var fmt_picker_span = $('<span/>');\n",
|
||
"\n",
|
||
" var fmt_picker = $('<select/>');\n",
|
||
" fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
|
||
" fmt_picker_span.append(fmt_picker);\n",
|
||
" nav_element.append(fmt_picker_span);\n",
|
||
" this.format_dropdown = fmt_picker[0];\n",
|
||
"\n",
|
||
" for (var ind in mpl.extensions) {\n",
|
||
" var fmt = mpl.extensions[ind];\n",
|
||
" var option = $(\n",
|
||
" '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
|
||
" fmt_picker.append(option)\n",
|
||
" }\n",
|
||
"\n",
|
||
" // Add hover states to the ui-buttons\n",
|
||
" $( \".ui-button\" ).hover(\n",
|
||
" function() { $(this).addClass(\"ui-state-hover\");},\n",
|
||
" function() { $(this).removeClass(\"ui-state-hover\");}\n",
|
||
" );\n",
|
||
"\n",
|
||
" var status_bar = $('<span class=\"mpl-message\"/>');\n",
|
||
" nav_element.append(status_bar);\n",
|
||
" this.message = status_bar[0];\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
|
||
" // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
|
||
" // which will in turn request a refresh of the image.\n",
|
||
" this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.send_message = function(type, properties) {\n",
|
||
" properties['type'] = type;\n",
|
||
" properties['figure_id'] = this.id;\n",
|
||
" this.ws.send(JSON.stringify(properties));\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.send_draw_message = function() {\n",
|
||
" if (!this.waiting) {\n",
|
||
" this.waiting = true;\n",
|
||
" this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
|
||
" }\n",
|
||
"}\n",
|
||
"\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
|
||
" var format_dropdown = fig.format_dropdown;\n",
|
||
" var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
|
||
" fig.ondownload(fig, format);\n",
|
||
"}\n",
|
||
"\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
|
||
" var size = msg['size'];\n",
|
||
" if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
|
||
" fig._resize_canvas(size[0], size[1]);\n",
|
||
" fig.send_message(\"refresh\", {});\n",
|
||
" };\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
|
||
" var x0 = msg['x0'] / mpl.ratio;\n",
|
||
" var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
|
||
" var x1 = msg['x1'] / mpl.ratio;\n",
|
||
" var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
|
||
" x0 = Math.floor(x0) + 0.5;\n",
|
||
" y0 = Math.floor(y0) + 0.5;\n",
|
||
" x1 = Math.floor(x1) + 0.5;\n",
|
||
" y1 = Math.floor(y1) + 0.5;\n",
|
||
" var min_x = Math.min(x0, x1);\n",
|
||
" var min_y = Math.min(y0, y1);\n",
|
||
" var width = Math.abs(x1 - x0);\n",
|
||
" var height = Math.abs(y1 - y0);\n",
|
||
"\n",
|
||
" fig.rubberband_context.clearRect(\n",
|
||
" 0, 0, fig.canvas.width, fig.canvas.height);\n",
|
||
"\n",
|
||
" fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
|
||
" // Updates the figure title.\n",
|
||
" fig.header.textContent = msg['label'];\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
|
||
" var cursor = msg['cursor'];\n",
|
||
" switch(cursor)\n",
|
||
" {\n",
|
||
" case 0:\n",
|
||
" cursor = 'pointer';\n",
|
||
" break;\n",
|
||
" case 1:\n",
|
||
" cursor = 'default';\n",
|
||
" break;\n",
|
||
" case 2:\n",
|
||
" cursor = 'crosshair';\n",
|
||
" break;\n",
|
||
" case 3:\n",
|
||
" cursor = 'move';\n",
|
||
" break;\n",
|
||
" }\n",
|
||
" fig.rubberband_canvas.style.cursor = cursor;\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_message = function(fig, msg) {\n",
|
||
" fig.message.textContent = msg['message'];\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
|
||
" // Request the server to send over a new figure.\n",
|
||
" fig.send_draw_message();\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
|
||
" fig.image_mode = msg['mode'];\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.updated_canvas_event = function() {\n",
|
||
" // Called whenever the canvas gets updated.\n",
|
||
" this.send_message(\"ack\", {});\n",
|
||
"}\n",
|
||
"\n",
|
||
"// A function to construct a web socket function for onmessage handling.\n",
|
||
"// Called in the figure constructor.\n",
|
||
"mpl.figure.prototype._make_on_message_function = function(fig) {\n",
|
||
" return function socket_on_message(evt) {\n",
|
||
" if (evt.data instanceof Blob) {\n",
|
||
" /* FIXME: We get \"Resource interpreted as Image but\n",
|
||
" * transferred with MIME type text/plain:\" errors on\n",
|
||
" * Chrome. But how to set the MIME type? It doesn't seem\n",
|
||
" * to be part of the websocket stream */\n",
|
||
" evt.data.type = \"image/png\";\n",
|
||
"\n",
|
||
" /* Free the memory for the previous frames */\n",
|
||
" if (fig.imageObj.src) {\n",
|
||
" (window.URL || window.webkitURL).revokeObjectURL(\n",
|
||
" fig.imageObj.src);\n",
|
||
" }\n",
|
||
"\n",
|
||
" fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
|
||
" evt.data);\n",
|
||
" fig.updated_canvas_event();\n",
|
||
" fig.waiting = false;\n",
|
||
" return;\n",
|
||
" }\n",
|
||
" else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
|
||
" fig.imageObj.src = evt.data;\n",
|
||
" fig.updated_canvas_event();\n",
|
||
" fig.waiting = false;\n",
|
||
" return;\n",
|
||
" }\n",
|
||
"\n",
|
||
" var msg = JSON.parse(evt.data);\n",
|
||
" var msg_type = msg['type'];\n",
|
||
"\n",
|
||
" // Call the \"handle_{type}\" callback, which takes\n",
|
||
" // the figure and JSON message as its only arguments.\n",
|
||
" try {\n",
|
||
" var callback = fig[\"handle_\" + msg_type];\n",
|
||
" } catch (e) {\n",
|
||
" console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
|
||
" return;\n",
|
||
" }\n",
|
||
"\n",
|
||
" if (callback) {\n",
|
||
" try {\n",
|
||
" // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
|
||
" callback(fig, msg);\n",
|
||
" } catch (e) {\n",
|
||
" console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
|
||
" }\n",
|
||
" }\n",
|
||
" };\n",
|
||
"}\n",
|
||
"\n",
|
||
"// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
|
||
"mpl.findpos = function(e) {\n",
|
||
" //this section is from http://www.quirksmode.org/js/events_properties.html\n",
|
||
" var targ;\n",
|
||
" if (!e)\n",
|
||
" e = window.event;\n",
|
||
" if (e.target)\n",
|
||
" targ = e.target;\n",
|
||
" else if (e.srcElement)\n",
|
||
" targ = e.srcElement;\n",
|
||
" if (targ.nodeType == 3) // defeat Safari bug\n",
|
||
" targ = targ.parentNode;\n",
|
||
"\n",
|
||
" // jQuery normalizes the pageX and pageY\n",
|
||
" // pageX,Y are the mouse positions relative to the document\n",
|
||
" // offset() returns the position of the element relative to the document\n",
|
||
" var x = e.pageX - $(targ).offset().left;\n",
|
||
" var y = e.pageY - $(targ).offset().top;\n",
|
||
"\n",
|
||
" return {\"x\": x, \"y\": y};\n",
|
||
"};\n",
|
||
"\n",
|
||
"/*\n",
|
||
" * return a copy of an object with only non-object keys\n",
|
||
" * we need this to avoid circular references\n",
|
||
" * http://stackoverflow.com/a/24161582/3208463\n",
|
||
" */\n",
|
||
"function simpleKeys (original) {\n",
|
||
" return Object.keys(original).reduce(function (obj, key) {\n",
|
||
" if (typeof original[key] !== 'object')\n",
|
||
" obj[key] = original[key]\n",
|
||
" return obj;\n",
|
||
" }, {});\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.mouse_event = function(event, name) {\n",
|
||
" var canvas_pos = mpl.findpos(event)\n",
|
||
"\n",
|
||
" if (name === 'button_press')\n",
|
||
" {\n",
|
||
" this.canvas.focus();\n",
|
||
" this.canvas_div.focus();\n",
|
||
" }\n",
|
||
"\n",
|
||
" var x = canvas_pos.x * mpl.ratio;\n",
|
||
" var y = canvas_pos.y * mpl.ratio;\n",
|
||
"\n",
|
||
" this.send_message(name, {x: x, y: y, button: event.button,\n",
|
||
" step: event.step,\n",
|
||
" guiEvent: simpleKeys(event)});\n",
|
||
"\n",
|
||
" /* This prevents the web browser from automatically changing to\n",
|
||
" * the text insertion cursor when the button is pressed. We want\n",
|
||
" * to control all of the cursor setting manually through the\n",
|
||
" * 'cursor' event from matplotlib */\n",
|
||
" event.preventDefault();\n",
|
||
" return false;\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
|
||
" // Handle any extra behaviour associated with a key event\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.key_event = function(event, name) {\n",
|
||
"\n",
|
||
" // Prevent repeat events\n",
|
||
" if (name == 'key_press')\n",
|
||
" {\n",
|
||
" if (event.which === this._key)\n",
|
||
" return;\n",
|
||
" else\n",
|
||
" this._key = event.which;\n",
|
||
" }\n",
|
||
" if (name == 'key_release')\n",
|
||
" this._key = null;\n",
|
||
"\n",
|
||
" var value = '';\n",
|
||
" if (event.ctrlKey && event.which != 17)\n",
|
||
" value += \"ctrl+\";\n",
|
||
" if (event.altKey && event.which != 18)\n",
|
||
" value += \"alt+\";\n",
|
||
" if (event.shiftKey && event.which != 16)\n",
|
||
" value += \"shift+\";\n",
|
||
"\n",
|
||
" value += 'k';\n",
|
||
" value += event.which.toString();\n",
|
||
"\n",
|
||
" this._key_event_extra(event, name);\n",
|
||
"\n",
|
||
" this.send_message(name, {key: value,\n",
|
||
" guiEvent: simpleKeys(event)});\n",
|
||
" return false;\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
|
||
" if (name == 'download') {\n",
|
||
" this.handle_save(this, null);\n",
|
||
" } else {\n",
|
||
" this.send_message(\"toolbar_button\", {name: name});\n",
|
||
" }\n",
|
||
"};\n",
|
||
"\n",
|
||
"mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
|
||
" this.message.textContent = tooltip;\n",
|
||
"};\n",
|
||
"mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
|
||
"\n",
|
||
"mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
|
||
"\n",
|
||
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
|
||
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
||
" // object with the appropriate methods. Currently this is a non binary\n",
|
||
" // socket, so there is still some room for performance tuning.\n",
|
||
" var ws = {};\n",
|
||
"\n",
|
||
" ws.close = function() {\n",
|
||
" comm.close()\n",
|
||
" };\n",
|
||
" ws.send = function(m) {\n",
|
||
" //console.log('sending', m);\n",
|
||
" comm.send(m);\n",
|
||
" };\n",
|
||
" // Register the callback with on_msg.\n",
|
||
" comm.on_msg(function(msg) {\n",
|
||
" //console.log('receiving', msg['content']['data'], msg);\n",
|
||
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
|
||
" ws.onmessage(msg['content']['data'])\n",
|
||
" });\n",
|
||
" return ws;\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.mpl_figure_comm = function(comm, msg) {\n",
|
||
" // This is the function which gets called when the mpl process\n",
|
||
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
||
"\n",
|
||
" var id = msg.content.data.id;\n",
|
||
" // Get hold of the div created by the display call when the Comm\n",
|
||
" // socket was opened in Python.\n",
|
||
" var element = $(\"#\" + id);\n",
|
||
" var ws_proxy = comm_websocket_adapter(comm)\n",
|
||
"\n",
|
||
" function ondownload(figure, format) {\n",
|
||
" window.open(figure.imageObj.src);\n",
|
||
" }\n",
|
||
"\n",
|
||
" var fig = new mpl.figure(id, ws_proxy,\n",
|
||
" ondownload,\n",
|
||
" element.get(0));\n",
|
||
"\n",
|
||
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
||
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
||
" ws_proxy.onopen();\n",
|
||
"\n",
|
||
" fig.parent_element = element.get(0);\n",
|
||
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
||
" if (!fig.cell_info) {\n",
|
||
" console.error(\"Failed to find cell for figure\", id, fig);\n",
|
||
" return;\n",
|
||
" }\n",
|
||
"\n",
|
||
" var output_index = fig.cell_info[2]\n",
|
||
" var cell = fig.cell_info[0];\n",
|
||
"\n",
|
||
"};\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
|
||
" var width = fig.canvas.width/mpl.ratio\n",
|
||
" fig.root.unbind('remove')\n",
|
||
"\n",
|
||
" // Update the output cell to use the data from the current canvas.\n",
|
||
" fig.push_to_output();\n",
|
||
" var dataURL = fig.canvas.toDataURL();\n",
|
||
" // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
|
||
" // the notebook keyboard shortcuts fail.\n",
|
||
" IPython.keyboard_manager.enable()\n",
|
||
" $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
|
||
" fig.close_ws(fig, msg);\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.close_ws = function(fig, msg){\n",
|
||
" fig.send_message('closing', msg);\n",
|
||
" // fig.ws.close()\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
|
||
" // Turn the data on the canvas into data in the output cell.\n",
|
||
" var width = this.canvas.width/mpl.ratio\n",
|
||
" var dataURL = this.canvas.toDataURL();\n",
|
||
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.updated_canvas_event = function() {\n",
|
||
" // Tell IPython that the notebook contents must change.\n",
|
||
" IPython.notebook.set_dirty(true);\n",
|
||
" this.send_message(\"ack\", {});\n",
|
||
" var fig = this;\n",
|
||
" // Wait a second, then push the new image to the DOM so\n",
|
||
" // that it is saved nicely (might be nice to debounce this).\n",
|
||
" setTimeout(function () { fig.push_to_output() }, 1000);\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype._init_toolbar = function() {\n",
|
||
" var fig = this;\n",
|
||
"\n",
|
||
" var nav_element = $('<div/>')\n",
|
||
" nav_element.attr('style', 'width: 100%');\n",
|
||
" this.root.append(nav_element);\n",
|
||
"\n",
|
||
" // Define a callback function for later on.\n",
|
||
" function toolbar_event(event) {\n",
|
||
" return fig.toolbar_button_onclick(event['data']);\n",
|
||
" }\n",
|
||
" function toolbar_mouse_event(event) {\n",
|
||
" return fig.toolbar_button_onmouseover(event['data']);\n",
|
||
" }\n",
|
||
"\n",
|
||
" for(var toolbar_ind in mpl.toolbar_items){\n",
|
||
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
|
||
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
|
||
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
|
||
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
|
||
"\n",
|
||
" if (!name) { continue; };\n",
|
||
"\n",
|
||
" var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
|
||
" button.click(method_name, toolbar_event);\n",
|
||
" button.mouseover(tooltip, toolbar_mouse_event);\n",
|
||
" nav_element.append(button);\n",
|
||
" }\n",
|
||
"\n",
|
||
" // Add the status bar.\n",
|
||
" var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
|
||
" nav_element.append(status_bar);\n",
|
||
" this.message = status_bar[0];\n",
|
||
"\n",
|
||
" // Add the close button to the window.\n",
|
||
" var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
|
||
" var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
|
||
" button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
|
||
" button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
|
||
" buttongrp.append(button);\n",
|
||
" var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
|
||
" titlebar.prepend(buttongrp);\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype._root_extra_style = function(el){\n",
|
||
" var fig = this\n",
|
||
" el.on(\"remove\", function(){\n",
|
||
"\tfig.close_ws(fig, {});\n",
|
||
" });\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype._canvas_extra_style = function(el){\n",
|
||
" // this is important to make the div 'focusable\n",
|
||
" el.attr('tabindex', 0)\n",
|
||
" // reach out to IPython and tell the keyboard manager to turn it's self\n",
|
||
" // off when our div gets focus\n",
|
||
"\n",
|
||
" // location in version 3\n",
|
||
" if (IPython.notebook.keyboard_manager) {\n",
|
||
" IPython.notebook.keyboard_manager.register_events(el);\n",
|
||
" }\n",
|
||
" else {\n",
|
||
" // location in version 2\n",
|
||
" IPython.keyboard_manager.register_events(el);\n",
|
||
" }\n",
|
||
"\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
|
||
" var manager = IPython.notebook.keyboard_manager;\n",
|
||
" if (!manager)\n",
|
||
" manager = IPython.keyboard_manager;\n",
|
||
"\n",
|
||
" // Check for shift+enter\n",
|
||
" if (event.shiftKey && event.which == 13) {\n",
|
||
" this.canvas_div.blur();\n",
|
||
" // select the cell after this one\n",
|
||
" var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
|
||
" IPython.notebook.select(index + 1);\n",
|
||
" }\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
|
||
" fig.ondownload(fig, null);\n",
|
||
"}\n",
|
||
"\n",
|
||
"\n",
|
||
"mpl.find_output_cell = function(html_output) {\n",
|
||
" // Return the cell and output element which can be found *uniquely* in the notebook.\n",
|
||
" // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
|
||
" // IPython event is triggered only after the cells have been serialised, which for\n",
|
||
" // our purposes (turning an active figure into a static one), is too late.\n",
|
||
" var cells = IPython.notebook.get_cells();\n",
|
||
" var ncells = cells.length;\n",
|
||
" for (var i=0; i<ncells; i++) {\n",
|
||
" var cell = cells[i];\n",
|
||
" if (cell.cell_type === 'code'){\n",
|
||
" for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
|
||
" var data = cell.output_area.outputs[j];\n",
|
||
" if (data.data) {\n",
|
||
" // IPython >= 3 moved mimebundle to data attribute of output\n",
|
||
" data = data.data;\n",
|
||
" }\n",
|
||
" if (data['text/html'] == html_output) {\n",
|
||
" return [cell, data, j];\n",
|
||
" }\n",
|
||
" }\n",
|
||
" }\n",
|
||
" }\n",
|
||
"}\n",
|
||
"\n",
|
||
"// Register the function which deals with the matplotlib target/channel.\n",
|
||
"// The kernel may be null if the page has been refreshed.\n",
|
||
"if (IPython.notebook.kernel != null) {\n",
|
||
" IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
|
||
"}\n"
|
||
],
|
||
"text/plain": [
|
||
"<IPython.core.display.Javascript object>"
|
||
]
|
||
},
|
||
"metadata": {},
|
||
"output_type": "display_data"
|
||
},
|
||
{
|
||
"data": {
|
||
"text/html": [
|
||
"<img src=\"data:image/png;base64,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\" width=\"640\">"
|
||
],
|
||
"text/plain": [
|
||
"<IPython.core.display.HTML object>"
|
||
]
|
||
},
|
||
"metadata": {},
|
||
"output_type": "display_data"
|
||
},
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"(380, 720)"
|
||
]
|
||
},
|
||
"execution_count": 124,
|
||
"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": 168,
|
||
"metadata": {
|
||
"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"
|
||
]
|
||
},
|
||
{
|
||
"data": {
|
||
"application/javascript": [
|
||
"/* Put everything inside the global mpl namespace */\n",
|
||
"window.mpl = {};\n",
|
||
"\n",
|
||
"\n",
|
||
"mpl.get_websocket_type = function() {\n",
|
||
" if (typeof(WebSocket) !== 'undefined') {\n",
|
||
" return WebSocket;\n",
|
||
" } else if (typeof(MozWebSocket) !== 'undefined') {\n",
|
||
" return MozWebSocket;\n",
|
||
" } else {\n",
|
||
" alert('Your browser does not have WebSocket support.' +\n",
|
||
" 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
|
||
" 'Firefox 4 and 5 are also supported but you ' +\n",
|
||
" 'have to enable WebSockets in about:config.');\n",
|
||
" };\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
|
||
" this.id = figure_id;\n",
|
||
"\n",
|
||
" this.ws = websocket;\n",
|
||
"\n",
|
||
" this.supports_binary = (this.ws.binaryType != undefined);\n",
|
||
"\n",
|
||
" if (!this.supports_binary) {\n",
|
||
" var warnings = document.getElementById(\"mpl-warnings\");\n",
|
||
" if (warnings) {\n",
|
||
" warnings.style.display = 'block';\n",
|
||
" warnings.textContent = (\n",
|
||
" \"This browser does not support binary websocket messages. \" +\n",
|
||
" \"Performance may be slow.\");\n",
|
||
" }\n",
|
||
" }\n",
|
||
"\n",
|
||
" this.imageObj = new Image();\n",
|
||
"\n",
|
||
" this.context = undefined;\n",
|
||
" this.message = undefined;\n",
|
||
" this.canvas = undefined;\n",
|
||
" this.rubberband_canvas = undefined;\n",
|
||
" this.rubberband_context = undefined;\n",
|
||
" this.format_dropdown = undefined;\n",
|
||
"\n",
|
||
" this.image_mode = 'full';\n",
|
||
"\n",
|
||
" this.root = $('<div/>');\n",
|
||
" this._root_extra_style(this.root)\n",
|
||
" this.root.attr('style', 'display: inline-block');\n",
|
||
"\n",
|
||
" $(parent_element).append(this.root);\n",
|
||
"\n",
|
||
" this._init_header(this);\n",
|
||
" this._init_canvas(this);\n",
|
||
" this._init_toolbar(this);\n",
|
||
"\n",
|
||
" var fig = this;\n",
|
||
"\n",
|
||
" this.waiting = false;\n",
|
||
"\n",
|
||
" this.ws.onopen = function () {\n",
|
||
" fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
|
||
" fig.send_message(\"send_image_mode\", {});\n",
|
||
" if (mpl.ratio != 1) {\n",
|
||
" fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
|
||
" }\n",
|
||
" fig.send_message(\"refresh\", {});\n",
|
||
" }\n",
|
||
"\n",
|
||
" this.imageObj.onload = function() {\n",
|
||
" if (fig.image_mode == 'full') {\n",
|
||
" // Full images could contain transparency (where diff images\n",
|
||
" // almost always do), so we need to clear the canvas so that\n",
|
||
" // there is no ghosting.\n",
|
||
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
||
" }\n",
|
||
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
||
" };\n",
|
||
"\n",
|
||
" this.imageObj.onunload = function() {\n",
|
||
" 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 backingStore = this.context.backingStorePixelRatio ||\n",
|
||
"\tthis.context.webkitBackingStorePixelRatio ||\n",
|
||
"\tthis.context.mozBackingStorePixelRatio ||\n",
|
||
"\tthis.context.msBackingStorePixelRatio ||\n",
|
||
"\tthis.context.oBackingStorePixelRatio ||\n",
|
||
"\tthis.context.backingStorePixelRatio || 1;\n",
|
||
"\n",
|
||
" mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
|
||
"\n",
|
||
" var rubberband = $('<canvas/>');\n",
|
||
" rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
|
||
"\n",
|
||
" var pass_mouse_events = true;\n",
|
||
"\n",
|
||
" canvas_div.resizable({\n",
|
||
" start: function(event, ui) {\n",
|
||
" pass_mouse_events = false;\n",
|
||
" },\n",
|
||
" resize: function(event, ui) {\n",
|
||
" fig.request_resize(ui.size.width, ui.size.height);\n",
|
||
" },\n",
|
||
" stop: function(event, ui) {\n",
|
||
" pass_mouse_events = true;\n",
|
||
" fig.request_resize(ui.size.width, ui.size.height);\n",
|
||
" },\n",
|
||
" });\n",
|
||
"\n",
|
||
" function mouse_event_fn(event) {\n",
|
||
" if (pass_mouse_events)\n",
|
||
" return fig.mouse_event(event, event['data']);\n",
|
||
" }\n",
|
||
"\n",
|
||
" rubberband.mousedown('button_press', mouse_event_fn);\n",
|
||
" rubberband.mouseup('button_release', mouse_event_fn);\n",
|
||
" // Throttle sequential mouse events to 1 every 20ms.\n",
|
||
" rubberband.mousemove('motion_notify', mouse_event_fn);\n",
|
||
"\n",
|
||
" rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
|
||
" rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
|
||
"\n",
|
||
" canvas_div.on(\"wheel\", function (event) {\n",
|
||
" event = event.originalEvent;\n",
|
||
" event['data'] = 'scroll'\n",
|
||
" if (event.deltaY < 0) {\n",
|
||
" event.step = 1;\n",
|
||
" } else {\n",
|
||
" event.step = -1;\n",
|
||
" }\n",
|
||
" mouse_event_fn(event);\n",
|
||
" });\n",
|
||
"\n",
|
||
" canvas_div.append(canvas);\n",
|
||
" canvas_div.append(rubberband);\n",
|
||
"\n",
|
||
" this.rubberband = rubberband;\n",
|
||
" this.rubberband_canvas = rubberband[0];\n",
|
||
" this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
|
||
" this.rubberband_context.strokeStyle = \"#000000\";\n",
|
||
"\n",
|
||
" this._resize_canvas = function(width, height) {\n",
|
||
" // Keep the size of the canvas, canvas container, and rubber band\n",
|
||
" // canvas in synch.\n",
|
||
" canvas_div.css('width', width)\n",
|
||
" canvas_div.css('height', height)\n",
|
||
"\n",
|
||
" canvas.attr('width', width * mpl.ratio);\n",
|
||
" canvas.attr('height', height * mpl.ratio);\n",
|
||
" canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
|
||
"\n",
|
||
" rubberband.attr('width', width);\n",
|
||
" rubberband.attr('height', height);\n",
|
||
" }\n",
|
||
"\n",
|
||
" // Set the figure to an initial 600x600px, this will subsequently be updated\n",
|
||
" // upon first draw.\n",
|
||
" this._resize_canvas(600, 600);\n",
|
||
"\n",
|
||
" // Disable right mouse context menu.\n",
|
||
" $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
|
||
" return false;\n",
|
||
" });\n",
|
||
"\n",
|
||
" function set_focus () {\n",
|
||
" canvas.focus();\n",
|
||
" canvas_div.focus();\n",
|
||
" }\n",
|
||
"\n",
|
||
" window.setTimeout(set_focus, 100);\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype._init_toolbar = function() {\n",
|
||
" var fig = this;\n",
|
||
"\n",
|
||
" var nav_element = $('<div/>')\n",
|
||
" nav_element.attr('style', 'width: 100%');\n",
|
||
" this.root.append(nav_element);\n",
|
||
"\n",
|
||
" // Define a callback function for later on.\n",
|
||
" function toolbar_event(event) {\n",
|
||
" return fig.toolbar_button_onclick(event['data']);\n",
|
||
" }\n",
|
||
" function toolbar_mouse_event(event) {\n",
|
||
" return fig.toolbar_button_onmouseover(event['data']);\n",
|
||
" }\n",
|
||
"\n",
|
||
" for(var toolbar_ind in mpl.toolbar_items) {\n",
|
||
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
|
||
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
|
||
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
|
||
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
|
||
"\n",
|
||
" if (!name) {\n",
|
||
" // put a spacer in here.\n",
|
||
" continue;\n",
|
||
" }\n",
|
||
" var button = $('<button/>');\n",
|
||
" button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
|
||
" 'ui-button-icon-only');\n",
|
||
" button.attr('role', 'button');\n",
|
||
" button.attr('aria-disabled', 'false');\n",
|
||
" button.click(method_name, toolbar_event);\n",
|
||
" button.mouseover(tooltip, toolbar_mouse_event);\n",
|
||
"\n",
|
||
" var icon_img = $('<span/>');\n",
|
||
" icon_img.addClass('ui-button-icon-primary ui-icon');\n",
|
||
" icon_img.addClass(image);\n",
|
||
" icon_img.addClass('ui-corner-all');\n",
|
||
"\n",
|
||
" var tooltip_span = $('<span/>');\n",
|
||
" tooltip_span.addClass('ui-button-text');\n",
|
||
" tooltip_span.html(tooltip);\n",
|
||
"\n",
|
||
" button.append(icon_img);\n",
|
||
" button.append(tooltip_span);\n",
|
||
"\n",
|
||
" nav_element.append(button);\n",
|
||
" }\n",
|
||
"\n",
|
||
" var fmt_picker_span = $('<span/>');\n",
|
||
"\n",
|
||
" var fmt_picker = $('<select/>');\n",
|
||
" fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
|
||
" fmt_picker_span.append(fmt_picker);\n",
|
||
" nav_element.append(fmt_picker_span);\n",
|
||
" this.format_dropdown = fmt_picker[0];\n",
|
||
"\n",
|
||
" for (var ind in mpl.extensions) {\n",
|
||
" var fmt = mpl.extensions[ind];\n",
|
||
" var option = $(\n",
|
||
" '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
|
||
" fmt_picker.append(option)\n",
|
||
" }\n",
|
||
"\n",
|
||
" // Add hover states to the ui-buttons\n",
|
||
" $( \".ui-button\" ).hover(\n",
|
||
" function() { $(this).addClass(\"ui-state-hover\");},\n",
|
||
" function() { $(this).removeClass(\"ui-state-hover\");}\n",
|
||
" );\n",
|
||
"\n",
|
||
" var status_bar = $('<span class=\"mpl-message\"/>');\n",
|
||
" nav_element.append(status_bar);\n",
|
||
" this.message = status_bar[0];\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
|
||
" // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
|
||
" // which will in turn request a refresh of the image.\n",
|
||
" this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.send_message = function(type, properties) {\n",
|
||
" properties['type'] = type;\n",
|
||
" properties['figure_id'] = this.id;\n",
|
||
" this.ws.send(JSON.stringify(properties));\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.send_draw_message = function() {\n",
|
||
" if (!this.waiting) {\n",
|
||
" this.waiting = true;\n",
|
||
" this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
|
||
" }\n",
|
||
"}\n",
|
||
"\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
|
||
" var format_dropdown = fig.format_dropdown;\n",
|
||
" var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
|
||
" fig.ondownload(fig, format);\n",
|
||
"}\n",
|
||
"\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
|
||
" var size = msg['size'];\n",
|
||
" if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
|
||
" fig._resize_canvas(size[0], size[1]);\n",
|
||
" fig.send_message(\"refresh\", {});\n",
|
||
" };\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
|
||
" var x0 = msg['x0'] / mpl.ratio;\n",
|
||
" var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
|
||
" var x1 = msg['x1'] / mpl.ratio;\n",
|
||
" var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
|
||
" x0 = Math.floor(x0) + 0.5;\n",
|
||
" y0 = Math.floor(y0) + 0.5;\n",
|
||
" x1 = Math.floor(x1) + 0.5;\n",
|
||
" y1 = Math.floor(y1) + 0.5;\n",
|
||
" var min_x = Math.min(x0, x1);\n",
|
||
" var min_y = Math.min(y0, y1);\n",
|
||
" var width = Math.abs(x1 - x0);\n",
|
||
" var height = Math.abs(y1 - y0);\n",
|
||
"\n",
|
||
" fig.rubberband_context.clearRect(\n",
|
||
" 0, 0, fig.canvas.width, fig.canvas.height);\n",
|
||
"\n",
|
||
" fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
|
||
" // Updates the figure title.\n",
|
||
" fig.header.textContent = msg['label'];\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
|
||
" var cursor = msg['cursor'];\n",
|
||
" switch(cursor)\n",
|
||
" {\n",
|
||
" case 0:\n",
|
||
" cursor = 'pointer';\n",
|
||
" break;\n",
|
||
" case 1:\n",
|
||
" cursor = 'default';\n",
|
||
" break;\n",
|
||
" case 2:\n",
|
||
" cursor = 'crosshair';\n",
|
||
" break;\n",
|
||
" case 3:\n",
|
||
" cursor = 'move';\n",
|
||
" break;\n",
|
||
" }\n",
|
||
" fig.rubberband_canvas.style.cursor = cursor;\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_message = function(fig, msg) {\n",
|
||
" fig.message.textContent = msg['message'];\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
|
||
" // Request the server to send over a new figure.\n",
|
||
" fig.send_draw_message();\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
|
||
" fig.image_mode = msg['mode'];\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.updated_canvas_event = function() {\n",
|
||
" // Called whenever the canvas gets updated.\n",
|
||
" this.send_message(\"ack\", {});\n",
|
||
"}\n",
|
||
"\n",
|
||
"// A function to construct a web socket function for onmessage handling.\n",
|
||
"// Called in the figure constructor.\n",
|
||
"mpl.figure.prototype._make_on_message_function = function(fig) {\n",
|
||
" return function socket_on_message(evt) {\n",
|
||
" if (evt.data instanceof Blob) {\n",
|
||
" /* FIXME: We get \"Resource interpreted as Image but\n",
|
||
" * transferred with MIME type text/plain:\" errors on\n",
|
||
" * Chrome. But how to set the MIME type? It doesn't seem\n",
|
||
" * to be part of the websocket stream */\n",
|
||
" evt.data.type = \"image/png\";\n",
|
||
"\n",
|
||
" /* Free the memory for the previous frames */\n",
|
||
" if (fig.imageObj.src) {\n",
|
||
" (window.URL || window.webkitURL).revokeObjectURL(\n",
|
||
" fig.imageObj.src);\n",
|
||
" }\n",
|
||
"\n",
|
||
" fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
|
||
" evt.data);\n",
|
||
" fig.updated_canvas_event();\n",
|
||
" fig.waiting = false;\n",
|
||
" return;\n",
|
||
" }\n",
|
||
" else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
|
||
" fig.imageObj.src = evt.data;\n",
|
||
" fig.updated_canvas_event();\n",
|
||
" fig.waiting = false;\n",
|
||
" return;\n",
|
||
" }\n",
|
||
"\n",
|
||
" var msg = JSON.parse(evt.data);\n",
|
||
" var msg_type = msg['type'];\n",
|
||
"\n",
|
||
" // Call the \"handle_{type}\" callback, which takes\n",
|
||
" // the figure and JSON message as its only arguments.\n",
|
||
" try {\n",
|
||
" var callback = fig[\"handle_\" + msg_type];\n",
|
||
" } catch (e) {\n",
|
||
" console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
|
||
" return;\n",
|
||
" }\n",
|
||
"\n",
|
||
" if (callback) {\n",
|
||
" try {\n",
|
||
" // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
|
||
" callback(fig, msg);\n",
|
||
" } catch (e) {\n",
|
||
" console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
|
||
" }\n",
|
||
" }\n",
|
||
" };\n",
|
||
"}\n",
|
||
"\n",
|
||
"// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
|
||
"mpl.findpos = function(e) {\n",
|
||
" //this section is from http://www.quirksmode.org/js/events_properties.html\n",
|
||
" var targ;\n",
|
||
" if (!e)\n",
|
||
" e = window.event;\n",
|
||
" if (e.target)\n",
|
||
" targ = e.target;\n",
|
||
" else if (e.srcElement)\n",
|
||
" targ = e.srcElement;\n",
|
||
" if (targ.nodeType == 3) // defeat Safari bug\n",
|
||
" targ = targ.parentNode;\n",
|
||
"\n",
|
||
" // jQuery normalizes the pageX and pageY\n",
|
||
" // pageX,Y are the mouse positions relative to the document\n",
|
||
" // offset() returns the position of the element relative to the document\n",
|
||
" var x = e.pageX - $(targ).offset().left;\n",
|
||
" var y = e.pageY - $(targ).offset().top;\n",
|
||
"\n",
|
||
" return {\"x\": x, \"y\": y};\n",
|
||
"};\n",
|
||
"\n",
|
||
"/*\n",
|
||
" * return a copy of an object with only non-object keys\n",
|
||
" * we need this to avoid circular references\n",
|
||
" * http://stackoverflow.com/a/24161582/3208463\n",
|
||
" */\n",
|
||
"function simpleKeys (original) {\n",
|
||
" return Object.keys(original).reduce(function (obj, key) {\n",
|
||
" if (typeof original[key] !== 'object')\n",
|
||
" obj[key] = original[key]\n",
|
||
" return obj;\n",
|
||
" }, {});\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.mouse_event = function(event, name) {\n",
|
||
" var canvas_pos = mpl.findpos(event)\n",
|
||
"\n",
|
||
" if (name === 'button_press')\n",
|
||
" {\n",
|
||
" this.canvas.focus();\n",
|
||
" this.canvas_div.focus();\n",
|
||
" }\n",
|
||
"\n",
|
||
" var x = canvas_pos.x * mpl.ratio;\n",
|
||
" var y = canvas_pos.y * mpl.ratio;\n",
|
||
"\n",
|
||
" this.send_message(name, {x: x, y: y, button: event.button,\n",
|
||
" step: event.step,\n",
|
||
" guiEvent: simpleKeys(event)});\n",
|
||
"\n",
|
||
" /* This prevents the web browser from automatically changing to\n",
|
||
" * the text insertion cursor when the button is pressed. We want\n",
|
||
" * to control all of the cursor setting manually through the\n",
|
||
" * 'cursor' event from matplotlib */\n",
|
||
" event.preventDefault();\n",
|
||
" return false;\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
|
||
" // Handle any extra behaviour associated with a key event\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.key_event = function(event, name) {\n",
|
||
"\n",
|
||
" // Prevent repeat events\n",
|
||
" if (name == 'key_press')\n",
|
||
" {\n",
|
||
" if (event.which === this._key)\n",
|
||
" return;\n",
|
||
" else\n",
|
||
" this._key = event.which;\n",
|
||
" }\n",
|
||
" if (name == 'key_release')\n",
|
||
" this._key = null;\n",
|
||
"\n",
|
||
" var value = '';\n",
|
||
" if (event.ctrlKey && event.which != 17)\n",
|
||
" value += \"ctrl+\";\n",
|
||
" if (event.altKey && event.which != 18)\n",
|
||
" value += \"alt+\";\n",
|
||
" if (event.shiftKey && event.which != 16)\n",
|
||
" value += \"shift+\";\n",
|
||
"\n",
|
||
" value += 'k';\n",
|
||
" value += event.which.toString();\n",
|
||
"\n",
|
||
" this._key_event_extra(event, name);\n",
|
||
"\n",
|
||
" this.send_message(name, {key: value,\n",
|
||
" guiEvent: simpleKeys(event)});\n",
|
||
" return false;\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
|
||
" if (name == 'download') {\n",
|
||
" this.handle_save(this, null);\n",
|
||
" } else {\n",
|
||
" this.send_message(\"toolbar_button\", {name: name});\n",
|
||
" }\n",
|
||
"};\n",
|
||
"\n",
|
||
"mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
|
||
" this.message.textContent = tooltip;\n",
|
||
"};\n",
|
||
"mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
|
||
"\n",
|
||
"mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
|
||
"\n",
|
||
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
|
||
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
||
" // object with the appropriate methods. Currently this is a non binary\n",
|
||
" // socket, so there is still some room for performance tuning.\n",
|
||
" var ws = {};\n",
|
||
"\n",
|
||
" ws.close = function() {\n",
|
||
" comm.close()\n",
|
||
" };\n",
|
||
" ws.send = function(m) {\n",
|
||
" //console.log('sending', m);\n",
|
||
" comm.send(m);\n",
|
||
" };\n",
|
||
" // Register the callback with on_msg.\n",
|
||
" comm.on_msg(function(msg) {\n",
|
||
" //console.log('receiving', msg['content']['data'], msg);\n",
|
||
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
|
||
" ws.onmessage(msg['content']['data'])\n",
|
||
" });\n",
|
||
" return ws;\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.mpl_figure_comm = function(comm, msg) {\n",
|
||
" // This is the function which gets called when the mpl process\n",
|
||
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
||
"\n",
|
||
" var id = msg.content.data.id;\n",
|
||
" // Get hold of the div created by the display call when the Comm\n",
|
||
" // socket was opened in Python.\n",
|
||
" var element = $(\"#\" + id);\n",
|
||
" var ws_proxy = comm_websocket_adapter(comm)\n",
|
||
"\n",
|
||
" function ondownload(figure, format) {\n",
|
||
" window.open(figure.imageObj.src);\n",
|
||
" }\n",
|
||
"\n",
|
||
" var fig = new mpl.figure(id, ws_proxy,\n",
|
||
" ondownload,\n",
|
||
" element.get(0));\n",
|
||
"\n",
|
||
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
||
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
||
" ws_proxy.onopen();\n",
|
||
"\n",
|
||
" fig.parent_element = element.get(0);\n",
|
||
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
||
" if (!fig.cell_info) {\n",
|
||
" console.error(\"Failed to find cell for figure\", id, fig);\n",
|
||
" return;\n",
|
||
" }\n",
|
||
"\n",
|
||
" var output_index = fig.cell_info[2]\n",
|
||
" var cell = fig.cell_info[0];\n",
|
||
"\n",
|
||
"};\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
|
||
" var width = fig.canvas.width/mpl.ratio\n",
|
||
" fig.root.unbind('remove')\n",
|
||
"\n",
|
||
" // Update the output cell to use the data from the current canvas.\n",
|
||
" fig.push_to_output();\n",
|
||
" var dataURL = fig.canvas.toDataURL();\n",
|
||
" // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
|
||
" // the notebook keyboard shortcuts fail.\n",
|
||
" IPython.keyboard_manager.enable()\n",
|
||
" $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
|
||
" fig.close_ws(fig, msg);\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.close_ws = function(fig, msg){\n",
|
||
" fig.send_message('closing', msg);\n",
|
||
" // fig.ws.close()\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
|
||
" // Turn the data on the canvas into data in the output cell.\n",
|
||
" var width = this.canvas.width/mpl.ratio\n",
|
||
" var dataURL = this.canvas.toDataURL();\n",
|
||
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.updated_canvas_event = function() {\n",
|
||
" // Tell IPython that the notebook contents must change.\n",
|
||
" IPython.notebook.set_dirty(true);\n",
|
||
" this.send_message(\"ack\", {});\n",
|
||
" var fig = this;\n",
|
||
" // Wait a second, then push the new image to the DOM so\n",
|
||
" // that it is saved nicely (might be nice to debounce this).\n",
|
||
" setTimeout(function () { fig.push_to_output() }, 1000);\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype._init_toolbar = function() {\n",
|
||
" var fig = this;\n",
|
||
"\n",
|
||
" var nav_element = $('<div/>')\n",
|
||
" nav_element.attr('style', 'width: 100%');\n",
|
||
" this.root.append(nav_element);\n",
|
||
"\n",
|
||
" // Define a callback function for later on.\n",
|
||
" function toolbar_event(event) {\n",
|
||
" return fig.toolbar_button_onclick(event['data']);\n",
|
||
" }\n",
|
||
" function toolbar_mouse_event(event) {\n",
|
||
" return fig.toolbar_button_onmouseover(event['data']);\n",
|
||
" }\n",
|
||
"\n",
|
||
" for(var toolbar_ind in mpl.toolbar_items){\n",
|
||
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
|
||
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
|
||
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
|
||
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
|
||
"\n",
|
||
" if (!name) { continue; };\n",
|
||
"\n",
|
||
" var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
|
||
" button.click(method_name, toolbar_event);\n",
|
||
" button.mouseover(tooltip, toolbar_mouse_event);\n",
|
||
" nav_element.append(button);\n",
|
||
" }\n",
|
||
"\n",
|
||
" // Add the status bar.\n",
|
||
" var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
|
||
" nav_element.append(status_bar);\n",
|
||
" this.message = status_bar[0];\n",
|
||
"\n",
|
||
" // Add the close button to the window.\n",
|
||
" var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
|
||
" var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
|
||
" button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
|
||
" button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
|
||
" buttongrp.append(button);\n",
|
||
" var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
|
||
" titlebar.prepend(buttongrp);\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype._root_extra_style = function(el){\n",
|
||
" var fig = this\n",
|
||
" el.on(\"remove\", function(){\n",
|
||
"\tfig.close_ws(fig, {});\n",
|
||
" });\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype._canvas_extra_style = function(el){\n",
|
||
" // this is important to make the div 'focusable\n",
|
||
" el.attr('tabindex', 0)\n",
|
||
" // reach out to IPython and tell the keyboard manager to turn it's self\n",
|
||
" // off when our div gets focus\n",
|
||
"\n",
|
||
" // location in version 3\n",
|
||
" if (IPython.notebook.keyboard_manager) {\n",
|
||
" IPython.notebook.keyboard_manager.register_events(el);\n",
|
||
" }\n",
|
||
" else {\n",
|
||
" // location in version 2\n",
|
||
" IPython.keyboard_manager.register_events(el);\n",
|
||
" }\n",
|
||
"\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
|
||
" var manager = IPython.notebook.keyboard_manager;\n",
|
||
" if (!manager)\n",
|
||
" manager = IPython.keyboard_manager;\n",
|
||
"\n",
|
||
" // Check for shift+enter\n",
|
||
" if (event.shiftKey && event.which == 13) {\n",
|
||
" this.canvas_div.blur();\n",
|
||
" // select the cell after this one\n",
|
||
" var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
|
||
" IPython.notebook.select(index + 1);\n",
|
||
" }\n",
|
||
"}\n",
|
||
"\n",
|
||
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
|
||
" fig.ondownload(fig, null);\n",
|
||
"}\n",
|
||
"\n",
|
||
"\n",
|
||
"mpl.find_output_cell = function(html_output) {\n",
|
||
" // Return the cell and output element which can be found *uniquely* in the notebook.\n",
|
||
" // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
|
||
" // IPython event is triggered only after the cells have been serialised, which for\n",
|
||
" // our purposes (turning an active figure into a static one), is too late.\n",
|
||
" var cells = IPython.notebook.get_cells();\n",
|
||
" var ncells = cells.length;\n",
|
||
" for (var i=0; i<ncells; i++) {\n",
|
||
" var cell = cells[i];\n",
|
||
" if (cell.cell_type === 'code'){\n",
|
||
" for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
|
||
" var data = cell.output_area.outputs[j];\n",
|
||
" if (data.data) {\n",
|
||
" // IPython >= 3 moved mimebundle to data attribute of output\n",
|
||
" data = data.data;\n",
|
||
" }\n",
|
||
" if (data['text/html'] == html_output) {\n",
|
||
" return [cell, data, j];\n",
|
||
" }\n",
|
||
" }\n",
|
||
" }\n",
|
||
" }\n",
|
||
"}\n",
|
||
"\n",
|
||
"// Register the function which deals with the matplotlib target/channel.\n",
|
||
"// The kernel may be null if the page has been refreshed.\n",
|
||
"if (IPython.notebook.kernel != null) {\n",
|
||
" IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
|
||
"}\n"
|
||
],
|
||
"text/plain": [
|
||
"<IPython.core.display.Javascript object>"
|
||
]
|
||
},
|
||
"metadata": {},
|
||
"output_type": "display_data"
|
||
},
|
||
{
|
||
"data": {
|
||
"text/html": [
|
||
"<img src=\"data:image/png;base64,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\" width=\"640\">"
|
||
],
|
||
"text/plain": [
|
||
"<IPython.core.display.HTML object>"
|
||
]
|
||
},
|
||
"metadata": {},
|
||
"output_type": "display_data"
|
||
},
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"spline_s 0.5\n"
|
||
]
|
||
}
|
||
],
|
||
"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",
|
||
"transimpedance = 630e6 # Ohms.\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",
|
||
"# Produce a first estimate for wavelength scaling. Use the short-wavelength edge of the blue band and the red peak\n",
|
||
"# for this, as both can be assumed to remain stable even after photodiode response compensation. Then apply photodiode\n",
|
||
"# response compensation and do another, second round of wavelength scaling estimation but this time using all three\n",
|
||
"# peaks and a proper least-squares fit.\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",
|
||
"\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_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",
|
||
"# Convert amplitude data to current in nanoampère\n",
|
||
"data_rgb = [ (λ, y/transimpedance / 1e-9, σ2/transimpedance / 1e-9) for λ, y, σ2 in data_rgb ]\n",
|
||
"\n",
|
||
"plot_rgb_bar(data_rgb, ids, spline_s=0.5, show_label=False, save_svg='/tmp/processed_plot_cheap_rgb.svg')"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 58,
|
||
"metadata": {
|
||
"collapsed": true
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"# CIE XYZ Color matching functions from http://cvrl.ioo.ucl.ac.uk/\n",
|
||
"# rows are: λ[nm], x, y, z\n",
|
||
"CMFs = { fn[:-4]: np.genfromtxt(fn, delimiter=',')\n",
|
||
" for fn in ['cie_xyz_1931.csv', 'cie_xyz_judd_1951.csv', 'cie_xyz_judd_vos_1978.csv'] }\n",
|
||
"CMFs = { name: np.hstack([inter.interp1d(d[:,0], d[:,i]) for i in range(1,4)])\n",
|
||
" for name, d in CMFs.items() }"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 59,
|
||
"metadata": {
|
||
"collapsed": true
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"def integrate_tristimulus_response(data, colorspace='cie_xyz_1931'):\n",
|
||
" a = np.array([[\n",
|
||
" integrate.simps(\n",
|
||
" np.multiply(CMFs[colorspace][j](data[i][0]), data[i][1]),\n",
|
||
" data[i][0])\n",
|
||
" for j in range(3) ]\n",
|
||
" for i in range(len(data)) ])\n",
|
||
" # normalize by largest component\n",
|
||
" return a / np.max(np.sum(a, axis=0))"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 60,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"array([[ 3.46142003e-01, 1.73335974e-01, -7.18827590e-05],\n",
|
||
" [ 9.01721797e-02, 1.69512416e-01, 2.15830281e-02],\n",
|
||
" [ 1.75128165e-01, 2.49230694e-01, 9.78488855e-01]])"
|
||
]
|
||
},
|
||
"execution_count": 60,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"tristimulus_data = integrate_tristimulus_response(data_rgb)\n",
|
||
"tristimulus_data"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 61,
|
||
"metadata": {
|
||
"collapsed": true
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"def led_setpoint_from_xyz(x, y, z):\n",
|
||
" # returns [r, g, b] array.\n",
|
||
" # Note that many xyz tristimulus values cannot be produced because one component is outside [0, 1]\n",
|
||
" #return np.linalg.solve(tristimulus_data.T, np.array([x, y, z]))\n",
|
||
" return np.dot(np.linalg.inv(tristimulus_data.T), np.array([x, y, z]))"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 62,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"array([ 0.72869072, 0.1386238 , 0.20139265])"
|
||
]
|
||
},
|
||
"execution_count": 62,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"led_setpoint_from_xyz(0.3, 0.2, 0.2)"
|
||
]
|
||
}
|
||
],
|
||
"metadata": {
|
||
"kernelspec": {
|
||
"display_name": "Python 3",
|
||
"language": "python",
|
||
"name": "python3"
|
||
},
|
||
"language_info": {
|
||
"codemirror_mode": {
|
||
"name": "ipython",
|
||
"version": 3
|
||
},
|
||
"file_extension": ".py",
|
||
"mimetype": "text/x-python",
|
||
"name": "python",
|
||
"nbconvert_exporter": "python",
|
||
"pygments_lexer": "ipython3",
|
||
"version": "3.6.5"
|
||
}
|
||
},
|
||
"nbformat": 4,
|
||
"nbformat_minor": 1
|
||
}
|