Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save corytodd/e55b7177100458ede1462fd3d19114e0 to your computer and use it in GitHub Desktop.
Save corytodd/e55b7177100458ede1462fd3d19114e0 to your computer and use it in GitHub Desktop.
Thermal Paper Roll Length Calculator
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "code",
"execution_count": 8,
"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": [
"%matplotlib nbagg\n",
"\n",
"import matplotlib.pyplot as plt\n",
"import numpy as np\n",
"\n",
"R = 150 # Roll diameter in mm\n",
"b = 0.0681 # Paper thickness in mm, 68.1 um\n",
"t = np.arange(1, R - 1 , 1) # Vary roll core by 1mm from 0 to\n",
"\n",
"def func(x):\n",
" '''Reduced volume formula where core diameter\n",
" \n",
" Args:\n",
" -----\n",
" x -- Roll core diameter in mm\n",
" \n",
" Returns:\n",
" --------\n",
" Length of roll in meters\n",
" '''\n",
" return (np.pi *(R**2-x**2)) / (4*b) / 1000\n",
"\n",
"plt.figure(1)\n",
"plt.plot(t, func(t), '-')\n",
"plt.ylabel('Total Roll Length')\n",
"plt.xlabel('Core Diameter')\n",
"plt.title('Core diamter vs Total Length')\n",
"plt.grid(True)\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 2",
"language": "python",
"name": "python2"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.13"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment