Skip to content

Instantly share code, notes, and snippets.

@zed
Last active February 6, 2018 10:34
Show Gist options
  • Save zed/d096104959af0d31166749f8a5c14058 to your computer and use it in GitHub Desktop.
Save zed/d096104959af0d31166749f8a5c14058 to your computer and use it in GitHub Desktop.
performance plots with pandas.ipynb
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"metadata": {
"trusted": false
},
"cell_type": "code",
"source": "run_long = False",
"execution_count": 1,
"outputs": []
},
{
"metadata": {
"trusted": false
},
"cell_type": "code",
"source": "import daedra # https://ru.stackoverflow.com/questions/775089",
"execution_count": 2,
"outputs": []
},
{
"metadata": {
"trusted": false
},
"cell_type": "code",
"source": "#! pip install https://gist.github.com/zed/4276624/archive/6027b408369e908b8221e66949c40cc2fea8f817.zip#egg=reporttime",
"execution_count": 3,
"outputs": []
},
{
"metadata": {
"trusted": false
},
"cell_type": "code",
"source": "def measure_times():\n import random\n from reporttime import get_functions_with_prefix, measure\n\n\n funcs = get_functions_with_prefix('sorted_', module=daedra)\n for comment, L in [\n (\"all same\", [1] * 10**2),\n (\"range\", list(range(10**2))),\n (\"random\", list(range(10**2)))]:\n if comment == \"random\":\n random.shuffle(L)\n measure(funcs, args=[L], comment=comment)\nif run_long: \n measure_times()",
"execution_count": 4,
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": "name time ratio comment\nsorted_insertion 20.6 usec 1.00 all same\nsorted_selection 568 usec 27.62 all same\nsorted_bubble 625 usec 30.41 all same\nname time ratio comment\nsorted_insertion 20.8 usec 1.00 range\nsorted_selection 584 usec 28.13 range\nsorted_bubble 649 usec 31.26 range\nname time ratio comment\nsorted_selection 587 usec 1.00 random\nsorted_insertion 603 usec 1.03 random\nsorted_bubble 1.21 msec 2.07 random\n"
}
]
},
{
"metadata": {
"trusted": false
},
"cell_type": "code",
"source": "times = {}\ndef collect_times():\n import random\n from reporttime import get_functions_with_prefix, measure_func\n global times\n for f in get_functions_with_prefix('sorted_', module=daedra):\n for N in range(6):\n for case, L in [\n (\"range\", list(range(10**N))),\n (\"random\", list(range(10**N)))]:\n if case == \"random\":\n random.shuffle(L)\n times[(f.__name__, case, N)] = measure_func(f, [L])\n \nif run_long: \n collect_times()\n\nimport pandas as pd\n\nfilename = 'performance.csv'\nif times:\n df = pd.DataFrame(dict(function=f, input=i, size=10**n, time=t) for (f,i,n), t in times.items())\n df.to_csv(filename)\nelse:\n df = pd.read_csv(filename)",
"execution_count": 6,
"outputs": []
},
{
"metadata": {
"trusted": false
},
"cell_type": "code",
"source": "%matplotlib notebook\n\nimport matplotlib.pyplot as plt\nplt.style.use('ggplot')\n\ndef plot_input(input):\n p = df[df.input==input].pivot(index='function', columns='size', values='time')\n p.T.plot(loglog=True, style='-o', title=input)\n return p",
"execution_count": 17,
"outputs": []
},
{
"metadata": {
"trusted": false
},
"cell_type": "code",
"source": "plot_input('range')",
"execution_count": 18,
"outputs": [
{
"data": {
"application/javascript": "/* Put everything inside the global mpl namespace */\nwindow.mpl = {};\n\n\nmpl.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\nmpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n this.id = figure_id;\n\n this.ws = websocket;\n\n this.supports_binary = (this.ws.binaryType != undefined);\n\n if (!this.supports_binary) {\n var warnings = document.getElementById(\"mpl-warnings\");\n if (warnings) {\n warnings.style.display = 'block';\n warnings.textContent = (\n \"This browser does not support binary websocket messages. \" +\n \"Performance may be slow.\");\n }\n }\n\n this.imageObj = new Image();\n\n this.context = undefined;\n this.message = undefined;\n this.canvas = undefined;\n this.rubberband_canvas = undefined;\n this.rubberband_context = undefined;\n this.format_dropdown = undefined;\n\n this.image_mode = 'full';\n\n this.root = $('<div/>');\n this._root_extra_style(this.root)\n this.root.attr('style', 'display: inline-block');\n\n $(parent_element).append(this.root);\n\n this._init_header(this);\n this._init_canvas(this);\n this._init_toolbar(this);\n\n var fig = this;\n\n this.waiting = false;\n\n this.ws.onopen = function () {\n fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n fig.send_message(\"send_image_mode\", {});\n if (mpl.ratio != 1) {\n fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n }\n fig.send_message(\"refresh\", {});\n }\n\n this.imageObj.onload = function() {\n if (fig.image_mode == 'full') {\n // Full images could contain transparency (where diff images\n // almost always do), so we need to clear the canvas so that\n // there is no ghosting.\n fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n }\n fig.context.drawImage(fig.imageObj, 0, 0);\n };\n\n this.imageObj.onunload = function() {\n fig.ws.close();\n }\n\n this.ws.onmessage = this._make_on_message_function(this);\n\n this.ondownload = ondownload;\n}\n\nmpl.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\nmpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n\n}\n\n\nmpl.figure.prototype._root_extra_style = function(canvas_div) {\n\n}\n\nmpl.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\nmpl.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\nmpl.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\nmpl.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\nmpl.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\nmpl.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\nmpl.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\nmpl.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\nmpl.figure.prototype.handle_figure_label = function(fig, msg) {\n // Updates the figure title.\n fig.header.textContent = msg['label'];\n}\n\nmpl.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\nmpl.figure.prototype.handle_message = function(fig, msg) {\n fig.message.textContent = msg['message'];\n}\n\nmpl.figure.prototype.handle_draw = function(fig, msg) {\n // Request the server to send over a new figure.\n fig.send_draw_message();\n}\n\nmpl.figure.prototype.handle_image_mode = function(fig, msg) {\n fig.image_mode = msg['mode'];\n}\n\nmpl.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.\nmpl.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\nmpl.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 */\nfunction 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\nmpl.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\nmpl.figure.prototype._key_event_extra = function(event, name) {\n // Handle any extra behaviour associated with a key event\n}\n\nmpl.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\nmpl.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\nmpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n this.message.textContent = tooltip;\n};\nmpl.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\nmpl.extensions = [\"eps\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n\nmpl.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\nmpl.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\nmpl.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\nmpl.figure.prototype.close_ws = function(fig, msg){\n fig.send_message('closing', msg);\n // fig.ws.close()\n}\n\nmpl.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\nmpl.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\nmpl.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\nmpl.figure.prototype._root_extra_style = function(el){\n var fig = this\n el.on(\"remove\", function(){\n\tfig.close_ws(fig, {});\n });\n}\n\nmpl.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\nmpl.figure.prototype._key_event_extra = function(event, name) {\n var manager = IPython.notebook.keyboard_manager;\n if (!manager)\n manager = IPython.keyboard_manager;\n\n // Check for shift+enter\n if (event.shiftKey && event.which == 13) {\n this.canvas_div.blur();\n event.shiftKey = false;\n // Send a \"J\" for go to next cell\n event.which = 74;\n event.keyCode = 74;\n manager.command_mode();\n manager.handle_keydown(event);\n }\n}\n\nmpl.figure.prototype.handle_save = function(fig, msg) {\n fig.ondownload(fig, null);\n}\n\n\nmpl.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.\nif (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/html": "<div>\n<style scoped>\n .dataframe tbody tr th:only-of-type {\n vertical-align: middle;\n }\n\n .dataframe tbody tr th {\n vertical-align: top;\n }\n\n .dataframe thead th {\n text-align: right;\n }\n</style>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th>size</th>\n <th>1</th>\n <th>10</th>\n <th>100</th>\n <th>1000</th>\n <th>10000</th>\n <th>100000</th>\n </tr>\n <tr>\n <th>function</th>\n <th></th>\n <th></th>\n <th></th>\n <th></th>\n <th></th>\n <th></th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>sorted_bubble</th>\n <td>0.000002</td>\n <td>0.000011</td>\n <td>0.000638</td>\n <td>0.062515</td>\n <td>6.235417</td>\n <td>631.393546</td>\n </tr>\n <tr>\n <th>sorted_insertion</th>\n <td>0.000002</td>\n <td>0.000004</td>\n <td>0.000021</td>\n <td>0.000205</td>\n <td>0.002078</td>\n <td>0.020855</td>\n </tr>\n <tr>\n <th>sorted_selection</th>\n <td>0.000002</td>\n <td>0.000013</td>\n <td>0.000580</td>\n <td>0.058093</td>\n <td>5.763568</td>\n <td>578.173501</td>\n </tr>\n </tbody>\n</table>\n</div>",
"text/plain": "size 1 10 100 1000 10000 100000\nfunction \nsorted_bubble 0.000002 0.000011 0.000638 0.062515 6.235417 631.393546\nsorted_insertion 0.000002 0.000004 0.000021 0.000205 0.002078 0.020855\nsorted_selection 0.000002 0.000013 0.000580 0.058093 5.763568 578.173501"
},
"execution_count": 18,
"metadata": {},
"output_type": "execute_result"
}
]
},
{
"metadata": {
"trusted": false
},
"cell_type": "code",
"source": "plot_input('random')",
"execution_count": 19,
"outputs": [
{
"data": {
"application/javascript": "/* Put everything inside the global mpl namespace */\nwindow.mpl = {};\n\n\nmpl.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\nmpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n this.id = figure_id;\n\n this.ws = websocket;\n\n this.supports_binary = (this.ws.binaryType != undefined);\n\n if (!this.supports_binary) {\n var warnings = document.getElementById(\"mpl-warnings\");\n if (warnings) {\n warnings.style.display = 'block';\n warnings.textContent = (\n \"This browser does not support binary websocket messages. \" +\n \"Performance may be slow.\");\n }\n }\n\n this.imageObj = new Image();\n\n this.context = undefined;\n this.message = undefined;\n this.canvas = undefined;\n this.rubberband_canvas = undefined;\n this.rubberband_context = undefined;\n this.format_dropdown = undefined;\n\n this.image_mode = 'full';\n\n this.root = $('<div/>');\n this._root_extra_style(this.root)\n this.root.attr('style', 'display: inline-block');\n\n $(parent_element).append(this.root);\n\n this._init_header(this);\n this._init_canvas(this);\n this._init_toolbar(this);\n\n var fig = this;\n\n this.waiting = false;\n\n this.ws.onopen = function () {\n fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n fig.send_message(\"send_image_mode\", {});\n if (mpl.ratio != 1) {\n fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n }\n fig.send_message(\"refresh\", {});\n }\n\n this.imageObj.onload = function() {\n if (fig.image_mode == 'full') {\n // Full images could contain transparency (where diff images\n // almost always do), so we need to clear the canvas so that\n // there is no ghosting.\n fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n }\n fig.context.drawImage(fig.imageObj, 0, 0);\n };\n\n this.imageObj.onunload = function() {\n fig.ws.close();\n }\n\n this.ws.onmessage = this._make_on_message_function(this);\n\n this.ondownload = ondownload;\n}\n\nmpl.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\nmpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n\n}\n\n\nmpl.figure.prototype._root_extra_style = function(canvas_div) {\n\n}\n\nmpl.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\nmpl.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\nmpl.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\nmpl.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\nmpl.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\nmpl.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\nmpl.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\nmpl.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\nmpl.figure.prototype.handle_figure_label = function(fig, msg) {\n // Updates the figure title.\n fig.header.textContent = msg['label'];\n}\n\nmpl.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\nmpl.figure.prototype.handle_message = function(fig, msg) {\n fig.message.textContent = msg['message'];\n}\n\nmpl.figure.prototype.handle_draw = function(fig, msg) {\n // Request the server to send over a new figure.\n fig.send_draw_message();\n}\n\nmpl.figure.prototype.handle_image_mode = function(fig, msg) {\n fig.image_mode = msg['mode'];\n}\n\nmpl.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.\nmpl.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\nmpl.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 */\nfunction 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\nmpl.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\nmpl.figure.prototype._key_event_extra = function(event, name) {\n // Handle any extra behaviour associated with a key event\n}\n\nmpl.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\nmpl.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\nmpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n this.message.textContent = tooltip;\n};\nmpl.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\nmpl.extensions = [\"eps\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n\nmpl.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\nmpl.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\nmpl.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\nmpl.figure.prototype.close_ws = function(fig, msg){\n fig.send_message('closing', msg);\n // fig.ws.close()\n}\n\nmpl.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\nmpl.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\nmpl.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\nmpl.figure.prototype._root_extra_style = function(el){\n var fig = this\n el.on(\"remove\", function(){\n\tfig.close_ws(fig, {});\n });\n}\n\nmpl.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\nmpl.figure.prototype._key_event_extra = function(event, name) {\n var manager = IPython.notebook.keyboard_manager;\n if (!manager)\n manager = IPython.keyboard_manager;\n\n // Check for shift+enter\n if (event.shiftKey && event.which == 13) {\n this.canvas_div.blur();\n event.shiftKey = false;\n // Send a \"J\" for go to next cell\n event.which = 74;\n event.keyCode = 74;\n manager.command_mode();\n manager.handle_keydown(event);\n }\n}\n\nmpl.figure.prototype.handle_save = function(fig, msg) {\n fig.ondownload(fig, null);\n}\n\n\nmpl.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.\nif (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/html": "<div>\n<style scoped>\n .dataframe tbody tr th:only-of-type {\n vertical-align: middle;\n }\n\n .dataframe tbody tr th {\n vertical-align: top;\n }\n\n .dataframe thead th {\n text-align: right;\n }\n</style>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th>size</th>\n <th>1</th>\n <th>10</th>\n <th>100</th>\n <th>1000</th>\n <th>10000</th>\n <th>100000</th>\n </tr>\n <tr>\n <th>function</th>\n <th></th>\n <th></th>\n <th></th>\n <th></th>\n <th></th>\n <th></th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>sorted_bubble</th>\n <td>0.000002</td>\n <td>0.000019</td>\n <td>0.001182</td>\n <td>0.125962</td>\n <td>12.893462</td>\n <td>1323.426973</td>\n </tr>\n <tr>\n <th>sorted_insertion</th>\n <td>0.000002</td>\n <td>0.000011</td>\n <td>0.000677</td>\n <td>0.069964</td>\n <td>7.196914</td>\n <td>726.325778</td>\n </tr>\n <tr>\n <th>sorted_selection</th>\n <td>0.000002</td>\n <td>0.000013</td>\n <td>0.000586</td>\n <td>0.058570</td>\n <td>5.819869</td>\n <td>613.853277</td>\n </tr>\n </tbody>\n</table>\n</div>",
"text/plain": "size 1 10 100 1000 10000 \\\nfunction \nsorted_bubble 0.000002 0.000019 0.001182 0.125962 12.893462 \nsorted_insertion 0.000002 0.000011 0.000677 0.069964 7.196914 \nsorted_selection 0.000002 0.000013 0.000586 0.058570 5.819869 \n\nsize 100000 \nfunction \nsorted_bubble 1323.426973 \nsorted_insertion 726.325778 \nsorted_selection 613.853277 "
},
"execution_count": 19,
"metadata": {},
"output_type": "execute_result"
}
]
},
{
"metadata": {
"trusted": false
},
"cell_type": "code",
"source": "p = df[df.function=='sorted_insertion'].pivot(index='input', columns='size', values='time')\np.T.plot(loglog=True, style='-o', title='sorted_insertion')\np",
"execution_count": 16,
"outputs": [
{
"data": {
"application/javascript": "/* Put everything inside the global mpl namespace */\nwindow.mpl = {};\n\n\nmpl.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\nmpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n this.id = figure_id;\n\n this.ws = websocket;\n\n this.supports_binary = (this.ws.binaryType != undefined);\n\n if (!this.supports_binary) {\n var warnings = document.getElementById(\"mpl-warnings\");\n if (warnings) {\n warnings.style.display = 'block';\n warnings.textContent = (\n \"This browser does not support binary websocket messages. \" +\n \"Performance may be slow.\");\n }\n }\n\n this.imageObj = new Image();\n\n this.context = undefined;\n this.message = undefined;\n this.canvas = undefined;\n this.rubberband_canvas = undefined;\n this.rubberband_context = undefined;\n this.format_dropdown = undefined;\n\n this.image_mode = 'full';\n\n this.root = $('<div/>');\n this._root_extra_style(this.root)\n this.root.attr('style', 'display: inline-block');\n\n $(parent_element).append(this.root);\n\n this._init_header(this);\n this._init_canvas(this);\n this._init_toolbar(this);\n\n var fig = this;\n\n this.waiting = false;\n\n this.ws.onopen = function () {\n fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n fig.send_message(\"send_image_mode\", {});\n if (mpl.ratio != 1) {\n fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n }\n fig.send_message(\"refresh\", {});\n }\n\n this.imageObj.onload = function() {\n if (fig.image_mode == 'full') {\n // Full images could contain transparency (where diff images\n // almost always do), so we need to clear the canvas so that\n // there is no ghosting.\n fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n }\n fig.context.drawImage(fig.imageObj, 0, 0);\n };\n\n this.imageObj.onunload = function() {\n fig.ws.close();\n }\n\n this.ws.onmessage = this._make_on_message_function(this);\n\n this.ondownload = ondownload;\n}\n\nmpl.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\nmpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n\n}\n\n\nmpl.figure.prototype._root_extra_style = function(canvas_div) {\n\n}\n\nmpl.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\nmpl.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\nmpl.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\nmpl.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\nmpl.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\nmpl.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\nmpl.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\nmpl.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\nmpl.figure.prototype.handle_figure_label = function(fig, msg) {\n // Updates the figure title.\n fig.header.textContent = msg['label'];\n}\n\nmpl.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\nmpl.figure.prototype.handle_message = function(fig, msg) {\n fig.message.textContent = msg['message'];\n}\n\nmpl.figure.prototype.handle_draw = function(fig, msg) {\n // Request the server to send over a new figure.\n fig.send_draw_message();\n}\n\nmpl.figure.prototype.handle_image_mode = function(fig, msg) {\n fig.image_mode = msg['mode'];\n}\n\nmpl.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.\nmpl.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\nmpl.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 */\nfunction 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\nmpl.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\nmpl.figure.prototype._key_event_extra = function(event, name) {\n // Handle any extra behaviour associated with a key event\n}\n\nmpl.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\nmpl.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\nmpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n this.message.textContent = tooltip;\n};\nmpl.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\nmpl.extensions = [\"eps\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n\nmpl.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\nmpl.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\nmpl.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\nmpl.figure.prototype.close_ws = function(fig, msg){\n fig.send_message('closing', msg);\n // fig.ws.close()\n}\n\nmpl.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\nmpl.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\nmpl.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\nmpl.figure.prototype._root_extra_style = function(el){\n var fig = this\n el.on(\"remove\", function(){\n\tfig.close_ws(fig, {});\n });\n}\n\nmpl.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\nmpl.figure.prototype._key_event_extra = function(event, name) {\n var manager = IPython.notebook.keyboard_manager;\n if (!manager)\n manager = IPython.keyboard_manager;\n\n // Check for shift+enter\n if (event.shiftKey && event.which == 13) {\n this.canvas_div.blur();\n event.shiftKey = false;\n // Send a \"J\" for go to next cell\n event.which = 74;\n event.keyCode = 74;\n manager.command_mode();\n manager.handle_keydown(event);\n }\n}\n\nmpl.figure.prototype.handle_save = function(fig, msg) {\n fig.ondownload(fig, null);\n}\n\n\nmpl.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.\nif (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/html": "<div>\n<style scoped>\n .dataframe tbody tr th:only-of-type {\n vertical-align: middle;\n }\n\n .dataframe tbody tr th {\n vertical-align: top;\n }\n\n .dataframe thead th {\n text-align: right;\n }\n</style>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th>size</th>\n <th>1</th>\n <th>10</th>\n <th>100</th>\n <th>1000</th>\n <th>10000</th>\n <th>100000</th>\n </tr>\n <tr>\n <th>input</th>\n <th></th>\n <th></th>\n <th></th>\n <th></th>\n <th></th>\n <th></th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>random</th>\n <td>0.000002</td>\n <td>0.000011</td>\n <td>0.000677</td>\n <td>0.069964</td>\n <td>7.196914</td>\n <td>726.325778</td>\n </tr>\n <tr>\n <th>range</th>\n <td>0.000002</td>\n <td>0.000004</td>\n <td>0.000021</td>\n <td>0.000205</td>\n <td>0.002078</td>\n <td>0.020855</td>\n </tr>\n </tbody>\n</table>\n</div>",
"text/plain": "size 1 10 100 1000 10000 100000\ninput \nrandom 0.000002 0.000011 0.000677 0.069964 7.196914 726.325778\nrange 0.000002 0.000004 0.000021 0.000205 0.002078 0.020855"
},
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
}
]
}
],
"metadata": {
"kernelspec": {
"name": "python3",
"display_name": "Python 3",
"language": "python"
},
"language_info": {
"name": "python",
"version": "3.6.3",
"mimetype": "text/x-python",
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"pygments_lexer": "ipython3",
"nbconvert_exporter": "python",
"file_extension": ".py"
},
"gist": {
"id": "",
"data": {
"description": "performance plots with pandas.ipynb",
"public": true
}
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment