Skip to content

Instantly share code, notes, and snippets.

@maxbellec
Created May 25, 2018 11:19
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 maxbellec/2d1b8f0bef35cc479a35988d0f1baab1 to your computer and use it in GitHub Desktop.
Save maxbellec/2d1b8f0bef35cc479a35988d0f1baab1 to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Importing"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"I almost always import the same libraries (`numpy`, `pandas`, `matplotlib`, `datetime`, ...). In order to avoid typing the same thing in all Notebooks, I do the imports in a module that exports all imports in `__all__`, so I can directly import everyting in a line. I also added a few custom functions I often use.\n",
"\n",
"I called the module `imports`, and put it in my `PYTHONPATH` (all my repositories are stored in `~/repos/` which is in my `PYTHONPATH`).\n",
"\n",
"*You can see that file at the very end of this Notebook.*"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"from imports import *"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Auto-restart external code"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"I use Notebooks only for quick coding, and save valuable functions (or classes) in proper files as soon as I realise it is important. I often edit the code (that's located in separate files) and want to use the updated functions immediately, without having to re-import everything or restart the Notebook. Thankfully, there's a way to do that :"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"%load_ext autoreload\n",
"%autoreload 2"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Zoomable plots"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"To have editable plots, use `%matplotlib notebook` or `%matplotlib qt5`. `%matplotlib inline` only produces static images, which I find quite frustrating. The difference between `notebook` or `qt5` is that `qt5` will open the figure in a separate window, which is often useful and sometimes a bit frustrating. Sadly, you can't switch between both in a single Notebook."
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"%matplotlib notebook"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"application/javascript": [
"/* Put everything inside the global mpl namespace */\n",
"window.mpl = {};\n",
"\n",
"\n",
"mpl.get_websocket_type = function() {\n",
" if (typeof(WebSocket) !== 'undefined') {\n",
" return WebSocket;\n",
" } else if (typeof(MozWebSocket) !== 'undefined') {\n",
" return MozWebSocket;\n",
" } else {\n",
" alert('Your browser does not have WebSocket support.' +\n",
" 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
" 'Firefox 4 and 5 are also supported but you ' +\n",
" 'have to enable WebSockets in about:config.');\n",
" };\n",
"}\n",
"\n",
"mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
" this.id = figure_id;\n",
"\n",
" this.ws = websocket;\n",
"\n",
" this.supports_binary = (this.ws.binaryType != undefined);\n",
"\n",
" if (!this.supports_binary) {\n",
" var warnings = document.getElementById(\"mpl-warnings\");\n",
" if (warnings) {\n",
" warnings.style.display = 'block';\n",
" warnings.textContent = (\n",
" \"This browser does not support binary websocket messages. \" +\n",
" \"Performance may be slow.\");\n",
" }\n",
" }\n",
"\n",
" this.imageObj = new Image();\n",
"\n",
" this.context = undefined;\n",
" this.message = undefined;\n",
" this.canvas = undefined;\n",
" this.rubberband_canvas = undefined;\n",
" this.rubberband_context = undefined;\n",
" this.format_dropdown = undefined;\n",
"\n",
" this.image_mode = 'full';\n",
"\n",
" this.root = $('<div/>');\n",
" this._root_extra_style(this.root)\n",
" this.root.attr('style', 'display: inline-block');\n",
"\n",
" $(parent_element).append(this.root);\n",
"\n",
" this._init_header(this);\n",
" this._init_canvas(this);\n",
" this._init_toolbar(this);\n",
"\n",
" var fig = this;\n",
"\n",
" this.waiting = false;\n",
"\n",
" this.ws.onopen = function () {\n",
" fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
" fig.send_message(\"send_image_mode\", {});\n",
" if (mpl.ratio != 1) {\n",
" fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
" }\n",
" fig.send_message(\"refresh\", {});\n",
" }\n",
"\n",
" this.imageObj.onload = function() {\n",
" if (fig.image_mode == 'full') {\n",
" // Full images could contain transparency (where diff images\n",
" // almost always do), so we need to clear the canvas so that\n",
" // there is no ghosting.\n",
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
" }\n",
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
" };\n",
"\n",
" this.imageObj.onunload = function() {\n",
" fig.ws.close();\n",
" }\n",
"\n",
" this.ws.onmessage = this._make_on_message_function(this);\n",
"\n",
" this.ondownload = ondownload;\n",
"}\n",
"\n",
"mpl.figure.prototype._init_header = function() {\n",
" var titlebar = $(\n",
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
" 'ui-helper-clearfix\"/>');\n",
" var titletext = $(\n",
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
" 'text-align: center; padding: 3px;\"/>');\n",
" titlebar.append(titletext)\n",
" this.root.append(titlebar);\n",
" this.header = titletext[0];\n",
"}\n",
"\n",
"\n",
"\n",
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
"\n",
"}\n",
"\n",
"\n",
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
"\n",
"}\n",
"\n",
"mpl.figure.prototype._init_canvas = function() {\n",
" var fig = this;\n",
"\n",
" var canvas_div = $('<div/>');\n",
"\n",
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
"\n",
" function canvas_keyboard_event(event) {\n",
" return fig.key_event(event, event['data']);\n",
" }\n",
"\n",
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
" this.canvas_div = canvas_div\n",
" this._canvas_extra_style(canvas_div)\n",
" this.root.append(canvas_div);\n",
"\n",
" var canvas = $('<canvas/>');\n",
" canvas.addClass('mpl-canvas');\n",
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
"\n",
" this.canvas = canvas[0];\n",
" this.context = canvas[0].getContext(\"2d\");\n",
"\n",
" var backingStore = this.context.backingStorePixelRatio ||\n",
"\tthis.context.webkitBackingStorePixelRatio ||\n",
"\tthis.context.mozBackingStorePixelRatio ||\n",
"\tthis.context.msBackingStorePixelRatio ||\n",
"\tthis.context.oBackingStorePixelRatio ||\n",
"\tthis.context.backingStorePixelRatio || 1;\n",
"\n",
" mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
"\n",
" var rubberband = $('<canvas/>');\n",
" rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
"\n",
" var pass_mouse_events = true;\n",
"\n",
" canvas_div.resizable({\n",
" start: function(event, ui) {\n",
" pass_mouse_events = false;\n",
" },\n",
" resize: function(event, ui) {\n",
" fig.request_resize(ui.size.width, ui.size.height);\n",
" },\n",
" stop: function(event, ui) {\n",
" pass_mouse_events = true;\n",
" fig.request_resize(ui.size.width, ui.size.height);\n",
" },\n",
" });\n",
"\n",
" function mouse_event_fn(event) {\n",
" if (pass_mouse_events)\n",
" return fig.mouse_event(event, event['data']);\n",
" }\n",
"\n",
" rubberband.mousedown('button_press', mouse_event_fn);\n",
" rubberband.mouseup('button_release', mouse_event_fn);\n",
" // Throttle sequential mouse events to 1 every 20ms.\n",
" rubberband.mousemove('motion_notify', mouse_event_fn);\n",
"\n",
" rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
" rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
"\n",
" canvas_div.on(\"wheel\", function (event) {\n",
" event = event.originalEvent;\n",
" event['data'] = 'scroll'\n",
" if (event.deltaY < 0) {\n",
" event.step = 1;\n",
" } else {\n",
" event.step = -1;\n",
" }\n",
" mouse_event_fn(event);\n",
" });\n",
"\n",
" canvas_div.append(canvas);\n",
" canvas_div.append(rubberband);\n",
"\n",
" this.rubberband = rubberband;\n",
" this.rubberband_canvas = rubberband[0];\n",
" this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
" this.rubberband_context.strokeStyle = \"#000000\";\n",
"\n",
" this._resize_canvas = function(width, height) {\n",
" // Keep the size of the canvas, canvas container, and rubber band\n",
" // canvas in synch.\n",
" canvas_div.css('width', width)\n",
" canvas_div.css('height', height)\n",
"\n",
" canvas.attr('width', width * mpl.ratio);\n",
" canvas.attr('height', height * mpl.ratio);\n",
" canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
"\n",
" rubberband.attr('width', width);\n",
" rubberband.attr('height', height);\n",
" }\n",
"\n",
" // Set the figure to an initial 600x600px, this will subsequently be updated\n",
" // upon first draw.\n",
" this._resize_canvas(600, 600);\n",
"\n",
" // Disable right mouse context menu.\n",
" $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
" return false;\n",
" });\n",
"\n",
" function set_focus () {\n",
" canvas.focus();\n",
" canvas_div.focus();\n",
" }\n",
"\n",
" window.setTimeout(set_focus, 100);\n",
"}\n",
"\n",
"mpl.figure.prototype._init_toolbar = function() {\n",
" var fig = this;\n",
"\n",
" var nav_element = $('<div/>')\n",
" nav_element.attr('style', 'width: 100%');\n",
" this.root.append(nav_element);\n",
"\n",
" // Define a callback function for later on.\n",
" function toolbar_event(event) {\n",
" return fig.toolbar_button_onclick(event['data']);\n",
" }\n",
" function toolbar_mouse_event(event) {\n",
" return fig.toolbar_button_onmouseover(event['data']);\n",
" }\n",
"\n",
" for(var toolbar_ind in mpl.toolbar_items) {\n",
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
"\n",
" if (!name) {\n",
" // put a spacer in here.\n",
" continue;\n",
" }\n",
" var button = $('<button/>');\n",
" button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
" 'ui-button-icon-only');\n",
" button.attr('role', 'button');\n",
" button.attr('aria-disabled', 'false');\n",
" button.click(method_name, toolbar_event);\n",
" button.mouseover(tooltip, toolbar_mouse_event);\n",
"\n",
" var icon_img = $('<span/>');\n",
" icon_img.addClass('ui-button-icon-primary ui-icon');\n",
" icon_img.addClass(image);\n",
" icon_img.addClass('ui-corner-all');\n",
"\n",
" var tooltip_span = $('<span/>');\n",
" tooltip_span.addClass('ui-button-text');\n",
" tooltip_span.html(tooltip);\n",
"\n",
" button.append(icon_img);\n",
" button.append(tooltip_span);\n",
"\n",
" nav_element.append(button);\n",
" }\n",
"\n",
" var fmt_picker_span = $('<span/>');\n",
"\n",
" var fmt_picker = $('<select/>');\n",
" fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
" fmt_picker_span.append(fmt_picker);\n",
" nav_element.append(fmt_picker_span);\n",
" this.format_dropdown = fmt_picker[0];\n",
"\n",
" for (var ind in mpl.extensions) {\n",
" var fmt = mpl.extensions[ind];\n",
" var option = $(\n",
" '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
" fmt_picker.append(option)\n",
" }\n",
"\n",
" // Add hover states to the ui-buttons\n",
" $( \".ui-button\" ).hover(\n",
" function() { $(this).addClass(\"ui-state-hover\");},\n",
" function() { $(this).removeClass(\"ui-state-hover\");}\n",
" );\n",
"\n",
" var status_bar = $('<span class=\"mpl-message\"/>');\n",
" nav_element.append(status_bar);\n",
" this.message = status_bar[0];\n",
"}\n",
"\n",
"mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
" // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
" // which will in turn request a refresh of the image.\n",
" this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
"}\n",
"\n",
"mpl.figure.prototype.send_message = function(type, properties) {\n",
" properties['type'] = type;\n",
" properties['figure_id'] = this.id;\n",
" this.ws.send(JSON.stringify(properties));\n",
"}\n",
"\n",
"mpl.figure.prototype.send_draw_message = function() {\n",
" if (!this.waiting) {\n",
" this.waiting = true;\n",
" this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
" }\n",
"}\n",
"\n",
"\n",
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
" var format_dropdown = fig.format_dropdown;\n",
" var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
" fig.ondownload(fig, format);\n",
"}\n",
"\n",
"\n",
"mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
" var size = msg['size'];\n",
" if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
" fig._resize_canvas(size[0], size[1]);\n",
" fig.send_message(\"refresh\", {});\n",
" };\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
" var x0 = msg['x0'] / mpl.ratio;\n",
" var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
" var x1 = msg['x1'] / mpl.ratio;\n",
" var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
" x0 = Math.floor(x0) + 0.5;\n",
" y0 = Math.floor(y0) + 0.5;\n",
" x1 = Math.floor(x1) + 0.5;\n",
" y1 = Math.floor(y1) + 0.5;\n",
" var min_x = Math.min(x0, x1);\n",
" var min_y = Math.min(y0, y1);\n",
" var width = Math.abs(x1 - x0);\n",
" var height = Math.abs(y1 - y0);\n",
"\n",
" fig.rubberband_context.clearRect(\n",
" 0, 0, fig.canvas.width, fig.canvas.height);\n",
"\n",
" fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
" // Updates the figure title.\n",
" fig.header.textContent = msg['label'];\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
" var cursor = msg['cursor'];\n",
" switch(cursor)\n",
" {\n",
" case 0:\n",
" cursor = 'pointer';\n",
" break;\n",
" case 1:\n",
" cursor = 'default';\n",
" break;\n",
" case 2:\n",
" cursor = 'crosshair';\n",
" break;\n",
" case 3:\n",
" cursor = 'move';\n",
" break;\n",
" }\n",
" fig.rubberband_canvas.style.cursor = cursor;\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_message = function(fig, msg) {\n",
" fig.message.textContent = msg['message'];\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
" // Request the server to send over a new figure.\n",
" fig.send_draw_message();\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
" fig.image_mode = msg['mode'];\n",
"}\n",
"\n",
"mpl.figure.prototype.updated_canvas_event = function() {\n",
" // Called whenever the canvas gets updated.\n",
" this.send_message(\"ack\", {});\n",
"}\n",
"\n",
"// A function to construct a web socket function for onmessage handling.\n",
"// Called in the figure constructor.\n",
"mpl.figure.prototype._make_on_message_function = function(fig) {\n",
" return function socket_on_message(evt) {\n",
" if (evt.data instanceof Blob) {\n",
" /* FIXME: We get \"Resource interpreted as Image but\n",
" * transferred with MIME type text/plain:\" errors on\n",
" * Chrome. But how to set the MIME type? It doesn't seem\n",
" * to be part of the websocket stream */\n",
" evt.data.type = \"image/png\";\n",
"\n",
" /* Free the memory for the previous frames */\n",
" if (fig.imageObj.src) {\n",
" (window.URL || window.webkitURL).revokeObjectURL(\n",
" fig.imageObj.src);\n",
" }\n",
"\n",
" fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
" evt.data);\n",
" fig.updated_canvas_event();\n",
" fig.waiting = false;\n",
" return;\n",
" }\n",
" else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
" fig.imageObj.src = evt.data;\n",
" fig.updated_canvas_event();\n",
" fig.waiting = false;\n",
" return;\n",
" }\n",
"\n",
" var msg = JSON.parse(evt.data);\n",
" var msg_type = msg['type'];\n",
"\n",
" // Call the \"handle_{type}\" callback, which takes\n",
" // the figure and JSON message as its only arguments.\n",
" try {\n",
" var callback = fig[\"handle_\" + msg_type];\n",
" } catch (e) {\n",
" console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
" return;\n",
" }\n",
"\n",
" if (callback) {\n",
" try {\n",
" // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
" callback(fig, msg);\n",
" } catch (e) {\n",
" console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
" }\n",
" }\n",
" };\n",
"}\n",
"\n",
"// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
"mpl.findpos = function(e) {\n",
" //this section is from http://www.quirksmode.org/js/events_properties.html\n",
" var targ;\n",
" if (!e)\n",
" e = window.event;\n",
" if (e.target)\n",
" targ = e.target;\n",
" else if (e.srcElement)\n",
" targ = e.srcElement;\n",
" if (targ.nodeType == 3) // defeat Safari bug\n",
" targ = targ.parentNode;\n",
"\n",
" // jQuery normalizes the pageX and pageY\n",
" // pageX,Y are the mouse positions relative to the document\n",
" // offset() returns the position of the element relative to the document\n",
" var x = e.pageX - $(targ).offset().left;\n",
" var y = e.pageY - $(targ).offset().top;\n",
"\n",
" return {\"x\": x, \"y\": y};\n",
"};\n",
"\n",
"/*\n",
" * return a copy of an object with only non-object keys\n",
" * we need this to avoid circular references\n",
" * http://stackoverflow.com/a/24161582/3208463\n",
" */\n",
"function simpleKeys (original) {\n",
" return Object.keys(original).reduce(function (obj, key) {\n",
" if (typeof original[key] !== 'object')\n",
" obj[key] = original[key]\n",
" return obj;\n",
" }, {});\n",
"}\n",
"\n",
"mpl.figure.prototype.mouse_event = function(event, name) {\n",
" var canvas_pos = mpl.findpos(event)\n",
"\n",
" if (name === 'button_press')\n",
" {\n",
" this.canvas.focus();\n",
" this.canvas_div.focus();\n",
" }\n",
"\n",
" var x = canvas_pos.x * mpl.ratio;\n",
" var y = canvas_pos.y * mpl.ratio;\n",
"\n",
" this.send_message(name, {x: x, y: y, button: event.button,\n",
" step: event.step,\n",
" guiEvent: simpleKeys(event)});\n",
"\n",
" /* This prevents the web browser from automatically changing to\n",
" * the text insertion cursor when the button is pressed. We want\n",
" * to control all of the cursor setting manually through the\n",
" * 'cursor' event from matplotlib */\n",
" event.preventDefault();\n",
" return false;\n",
"}\n",
"\n",
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
" // Handle any extra behaviour associated with a key event\n",
"}\n",
"\n",
"mpl.figure.prototype.key_event = function(event, name) {\n",
"\n",
" // Prevent repeat events\n",
" if (name == 'key_press')\n",
" {\n",
" if (event.which === this._key)\n",
" return;\n",
" else\n",
" this._key = event.which;\n",
" }\n",
" if (name == 'key_release')\n",
" this._key = null;\n",
"\n",
" var value = '';\n",
" if (event.ctrlKey && event.which != 17)\n",
" value += \"ctrl+\";\n",
" if (event.altKey && event.which != 18)\n",
" value += \"alt+\";\n",
" if (event.shiftKey && event.which != 16)\n",
" value += \"shift+\";\n",
"\n",
" value += 'k';\n",
" value += event.which.toString();\n",
"\n",
" this._key_event_extra(event, name);\n",
"\n",
" this.send_message(name, {key: value,\n",
" guiEvent: simpleKeys(event)});\n",
" return false;\n",
"}\n",
"\n",
"mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
" if (name == 'download') {\n",
" this.handle_save(this, null);\n",
" } else {\n",
" this.send_message(\"toolbar_button\", {name: name});\n",
" }\n",
"};\n",
"\n",
"mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
" this.message.textContent = tooltip;\n",
"};\n",
"mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
"\n",
"mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
"\n",
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
" // object with the appropriate methods. Currently this is a non binary\n",
" // socket, so there is still some room for performance tuning.\n",
" var ws = {};\n",
"\n",
" ws.close = function() {\n",
" comm.close()\n",
" };\n",
" ws.send = function(m) {\n",
" //console.log('sending', m);\n",
" comm.send(m);\n",
" };\n",
" // Register the callback with on_msg.\n",
" comm.on_msg(function(msg) {\n",
" //console.log('receiving', msg['content']['data'], msg);\n",
" // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
" ws.onmessage(msg['content']['data'])\n",
" });\n",
" return ws;\n",
"}\n",
"\n",
"mpl.mpl_figure_comm = function(comm, msg) {\n",
" // This is the function which gets called when the mpl process\n",
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
"\n",
" var id = msg.content.data.id;\n",
" // Get hold of the div created by the display call when the Comm\n",
" // socket was opened in Python.\n",
" var element = $(\"#\" + id);\n",
" var ws_proxy = comm_websocket_adapter(comm)\n",
"\n",
" function ondownload(figure, format) {\n",
" window.open(figure.imageObj.src);\n",
" }\n",
"\n",
" var fig = new mpl.figure(id, ws_proxy,\n",
" ondownload,\n",
" element.get(0));\n",
"\n",
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
" // web socket which is closed, not our websocket->open comm proxy.\n",
" ws_proxy.onopen();\n",
"\n",
" fig.parent_element = element.get(0);\n",
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
" if (!fig.cell_info) {\n",
" console.error(\"Failed to find cell for figure\", id, fig);\n",
" return;\n",
" }\n",
"\n",
" var output_index = fig.cell_info[2]\n",
" var cell = fig.cell_info[0];\n",
"\n",
"};\n",
"\n",
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
" var width = fig.canvas.width/mpl.ratio\n",
" fig.root.unbind('remove')\n",
"\n",
" // Update the output cell to use the data from the current canvas.\n",
" fig.push_to_output();\n",
" var dataURL = fig.canvas.toDataURL();\n",
" // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
" // the notebook keyboard shortcuts fail.\n",
" IPython.keyboard_manager.enable()\n",
" $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
" fig.close_ws(fig, msg);\n",
"}\n",
"\n",
"mpl.figure.prototype.close_ws = function(fig, msg){\n",
" fig.send_message('closing', msg);\n",
" // fig.ws.close()\n",
"}\n",
"\n",
"mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
" // Turn the data on the canvas into data in the output cell.\n",
" var width = this.canvas.width/mpl.ratio\n",
" var dataURL = this.canvas.toDataURL();\n",
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
"}\n",
"\n",
"mpl.figure.prototype.updated_canvas_event = function() {\n",
" // Tell IPython that the notebook contents must change.\n",
" IPython.notebook.set_dirty(true);\n",
" this.send_message(\"ack\", {});\n",
" var fig = this;\n",
" // Wait a second, then push the new image to the DOM so\n",
" // that it is saved nicely (might be nice to debounce this).\n",
" setTimeout(function () { fig.push_to_output() }, 1000);\n",
"}\n",
"\n",
"mpl.figure.prototype._init_toolbar = function() {\n",
" var fig = this;\n",
"\n",
" var nav_element = $('<div/>')\n",
" nav_element.attr('style', 'width: 100%');\n",
" this.root.append(nav_element);\n",
"\n",
" // Define a callback function for later on.\n",
" function toolbar_event(event) {\n",
" return fig.toolbar_button_onclick(event['data']);\n",
" }\n",
" function toolbar_mouse_event(event) {\n",
" return fig.toolbar_button_onmouseover(event['data']);\n",
" }\n",
"\n",
" for(var toolbar_ind in mpl.toolbar_items){\n",
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
"\n",
" if (!name) { continue; };\n",
"\n",
" var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
" button.click(method_name, toolbar_event);\n",
" button.mouseover(tooltip, toolbar_mouse_event);\n",
" nav_element.append(button);\n",
" }\n",
"\n",
" // Add the status bar.\n",
" var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
" nav_element.append(status_bar);\n",
" this.message = status_bar[0];\n",
"\n",
" // Add the close button to the window.\n",
" var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
" var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
" button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
" button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
" buttongrp.append(button);\n",
" var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
" titlebar.prepend(buttongrp);\n",
"}\n",
"\n",
"mpl.figure.prototype._root_extra_style = function(el){\n",
" var fig = this\n",
" el.on(\"remove\", function(){\n",
"\tfig.close_ws(fig, {});\n",
" });\n",
"}\n",
"\n",
"mpl.figure.prototype._canvas_extra_style = function(el){\n",
" // this is important to make the div 'focusable\n",
" el.attr('tabindex', 0)\n",
" // reach out to IPython and tell the keyboard manager to turn it's self\n",
" // off when our div gets focus\n",
"\n",
" // location in version 3\n",
" if (IPython.notebook.keyboard_manager) {\n",
" IPython.notebook.keyboard_manager.register_events(el);\n",
" }\n",
" else {\n",
" // location in version 2\n",
" IPython.keyboard_manager.register_events(el);\n",
" }\n",
"\n",
"}\n",
"\n",
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
" var manager = IPython.notebook.keyboard_manager;\n",
" if (!manager)\n",
" manager = IPython.keyboard_manager;\n",
"\n",
" // Check for shift+enter\n",
" if (event.shiftKey && event.which == 13) {\n",
" this.canvas_div.blur();\n",
" event.shiftKey = false;\n",
" // Send a \"J\" for go to next cell\n",
" event.which = 74;\n",
" event.keyCode = 74;\n",
" manager.command_mode();\n",
" manager.handle_keydown(event);\n",
" }\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
" fig.ondownload(fig, null);\n",
"}\n",
"\n",
"\n",
"mpl.find_output_cell = function(html_output) {\n",
" // Return the cell and output element which can be found *uniquely* in the notebook.\n",
" // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
" // IPython event is triggered only after the cells have been serialised, which for\n",
" // our purposes (turning an active figure into a static one), is too late.\n",
" var cells = IPython.notebook.get_cells();\n",
" var ncells = cells.length;\n",
" for (var i=0; i<ncells; i++) {\n",
" var cell = cells[i];\n",
" if (cell.cell_type === 'code'){\n",
" for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
" var data = cell.output_area.outputs[j];\n",
" if (data.data) {\n",
" // IPython >= 3 moved mimebundle to data attribute of output\n",
" data = data.data;\n",
" }\n",
" if (data['text/html'] == html_output) {\n",
" return [cell, data, j];\n",
" }\n",
" }\n",
" }\n",
" }\n",
"}\n",
"\n",
"// Register the function which deals with the matplotlib target/channel.\n",
"// The kernel may be null if the page has been refreshed.\n",
"if (IPython.notebook.kernel != null) {\n",
" IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
"}\n"
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<img src=\"data:image/png;base64,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\" width=\"640\">"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"[<matplotlib.lines.Line2D at 0x7f2219280128>]"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"plt.plot(np.random.randn(1000).cumsum())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Use the commands just above this cell to zoom in the plot!\n",
"\n",
"You can later alter the plot:"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Text(35.4722,0.5,'valuation [M$]')"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"plt.grid()\n",
"plt.title('bitcoin valuation history')\n",
"plt.xlabel('time [s]')\n",
"plt.ylabel('valuation [M$]')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"When I have a figure I like, I save it using a function from my `imports` module. The next line automatically saves the figure in my `$HOME/figures/YYYYMMDD` folder."
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"save_fig('bitcoin valuation history')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Documentation"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"When you're unsure about function arguments, use `Shift` + `Tab` when you're between brackets to get arguments.\n",
"\n",
"If you keep pressing `Shift` and press `Tab` twice, you will open a larger scrollable box to read the full documentation. If you want an even larger box, press `Tab` four times, a big box will appear at the bottom of the screen.\n",
"\n",
"Test when the cursor is **between the brackets** in the next cell."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"pd.Series.describe()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Use keyboard Shortcuts!\n",
"There a two editing modes when you're in a notebook :\n",
"- the edit mode (when the cursor is active in a cell, no special shortcut here). When a cell is selected, press enter to go to edit mode\n",
"- the command mode. When there is no active cursor in a cell, keyboard shortcuts are used for general settings or cell management. Press `Esc` or click outside a cell to enter command mode.\n",
"\n",
"In command mode, shortucts consist (mostly) of pressing a single key, no need for the `Ctrl` or `Cmd` key. Press `h` to list the shortcuts. The shortcuts I find most useful are:\n",
"- `Shift` + `m`. Merge current cell with cell below. Great for quickly transforming lines to a function\n",
"- `k` select cell up\n",
"- `j` select cell down. Very useful for quick navigation inside a Notebook\n",
"- `Shift` + `k`/`j` select cell up / down\n",
"- `c` copy cell(s) (you can copy / past multiple cells)\n",
"- `v` paste cell(s) below\n",
"- `x` delete cell\n",
"- `u` undo delete cell (doesn't undo other actions)\n",
"- I also like being able to move cells with `Ctrl` + `k` (up) or `Ctrl` + `j` (down). To enable it, add in you `~/.jupyter/custom/custom.js` (or create it if it doesn't exist)\n",
"\n",
"```javascript\n",
"define([\"base/js/namespace\"], function(Jupyter){\n",
" console.info('Binding Ctrl-J/K to move cell up/down');\n",
" Jupyter.keyboard_manager.command_shortcuts.add_shortcut('Ctrl-k','jupyter-notebook:move-cell-up');\n",
" Jupyter.keyboard_manager.command_shortcuts.add_shortcut('Ctrl-j','jupyter-notebook:move-cell-down');\n",
"});\n",
"```\n",
"\n",
"On additional shortcut, valid in edit mode (inside a cell)\n",
"- `Ctrl` + `Shift` + `-`. Break the current cell at cursor"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Sublime-like multiple cursor\n",
"\n",
"When you holding `Ctrl` down, each click will create a new cursor. If you want to be able to select next text occurence with `Ctrl` + `D`, Sublime-Text-like, add this to your `~/.jupyter/custom/custom.js`:\n",
"\n",
"```javascript\n",
"// http://blog.rtwilson.com/how-to-get-sublime-text-style-editing-in-the-ipythonjupyter-notebook/\n",
"require([\"codemirror/keymap/sublime\", \"notebook/js/cell\", \"base/js/namespace\"],\n",
" function(sublime_keymap, cell, IPython) {\n",
" \tconsole.info('codemirror sublime keymap');\n",
" // setTimeout(function(){ // uncomment line to fake race-condition\n",
" cell.Cell.options_default.cm_config.keyMap = 'sublime';\n",
" var cells = IPython.notebook.get_cells();\n",
" for(var cl=0; cl< cells.length ; cl++){\n",
" cells[cl].code_mirror.setOption('keyMap', 'sublime');\n",
" }\n",
" \n",
" // }, 1000)// uncomment line to fake race condition \n",
" } \n",
");\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Memory and time profiling\n",
"\n",
"Want to know how efficient, in terms of computation time and memory your code is? Or compare implementations?"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"def f_string_interpolation(str1, str2):\n",
" return f'{str1}{str2}'\n",
"\n",
"def string_sum(str1, str2):\n",
" return str1 + str2\n",
"\n",
"def string_format(str1, str2):\n",
" return \"{}{}\".format(str1, str2)"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"import string"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [],
"source": [
"str1 = ''.join([random.choice(string.ascii_letters)\n",
" for _ in range(1000)])\n",
"str2 = ''.join([random.choice(string.ascii_letters)\n",
" for _ in range(1000)])"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"205 ns ± 2.3 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)\n"
]
}
],
"source": [
"%%timeit\n",
"f_string_interpolation(str1, str2)"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"184 ns ± 4.37 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)\n"
]
}
],
"source": [
"%%timeit\n",
"string_sum(str1, str2)"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"353 ns ± 5.92 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)\n"
]
}
],
"source": [
"%%timeit\n",
"string_format(str1, str2)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Note that `%%timeit` is great for only for profiling and any code run inside will have no effect on what you do. If you want to know how much time a function takes but run it once, use `%%time`:"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"CPU times: user 0 ns, sys: 0 ns, total: 0 ns\n",
"Wall time: 2 s\n"
]
}
],
"source": [
"%%time\n",
"time.sleep(2)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"For memory profiling, you first need to"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [],
"source": [
"%load_ext memory_profiler"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Then you're good to go"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"peak memory: 207.08 MiB, increment: 71.15 MiB\n"
]
}
],
"source": [
"%%memit\n",
"np.array([np.random.randn(1000)\n",
" for _ in range(10000)])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Awesome progress bar\n",
"Whenever I run something take can take a long time, I love to have a progress bar. tqdm makes it crazy easy.\n",
"\n",
"When inside a notebook, use `tqdm.tqdm_notebook` for a beautifoul html progress bar, and use `tqdm.tqdm` for console output.\n",
"\n",
"Just do a normal for loop, and wrap whatever is after `in` in `tqdm_notebook`:"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "efef9e3ea81d443ab4e0945979bbe04d",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"HBox(children=(IntProgress(value=0, max=5000000), HTML(value='')))"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n"
]
}
],
"source": [
"for value in tqdm_notebook(np.random.randn(5 * MILLION)):\n",
" value**2"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"if you give an iterator, tqdm_notebook won't know the length, but you can give it to him."
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "7a5242b0653d496c8a132fa8974872d3",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"HBox(children=(IntProgress(value=0, description='awesome!', max=5000000), HTML(value='')))"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n"
]
}
],
"source": [
"for i, value in tqdm_notebook(enumerate(np.random.randn(5 * MILLION)),\n",
" total=5 * MILLION,\n",
" desc='awesome!'):\n",
" value**2"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You get progress bar, ETA, number of iteration per seconds for free! 🎉"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"As mentioned above, this is the content of my `imports` module, consisting of a single `__init__.py` file."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# %load /home/m/repos/imports/__init__.py\n",
"import pandas as pd\n",
"from pandas import DataFrame, Series\n",
"import numpy as np\n",
"from numpy import array\n",
"import matplotlib.pyplot as plt\n",
"from matplotlib.pyplot import plot, figure, scatter\n",
"import os\n",
"import sys\n",
"import scipy\n",
"import datetime\n",
"from tqdm import tqdm, tqdm_notebook\n",
"import sklearn\n",
"import json\n",
"import operator\n",
"import collections\n",
"import random\n",
"import time\n",
"import arrow\n",
"from IPython.core.debugger import set_trace\n",
"\n",
"THOUSAND = 1000\n",
"MILLION = THOUSAND**2\n",
"BILLION = THOUSAND**3\n",
"\n",
"\n",
"def save_fig(name=None, dpi=300, transparent=False, overwrite=False):\n",
" if name is None:\n",
" name = plt.gca().get_title()\n",
" assert name, \"if not passing a name, current plot should a title\"\n",
" plt.tight_layout()\n",
" dest_folder = os.path.join(os.environ['HOME'], 'figures',\n",
" datetime.date.today().strftime('%Y%m%d'))\n",
" os.makedirs(dest_folder, exist_ok=True)\n",
" target_path = os.path.join(dest_folder, name)\n",
" if os.path.isfile(target_path) and not overwrite:\n",
" raise ValueError('target file ({}) already exists. Re-launch with '\n",
" '`overwrite=True` to overwrite file'.format(\n",
" target_path))\n",
"\n",
" plt.savefig(target_path, dpi=dpi, transparent=transparent)\n",
"\n",
"\n",
"def new_plot(*args, **kwargs):\n",
" plt.figure()\n",
" title = kwargs.pop('title', False)\n",
" plt.plot(*args, **kwargs)\n",
" plt.grid()\n",
" if title:\n",
" plt.title(title)\n",
" plt.tight_layout()\n",
"\n",
"\n",
"def describe(x):\n",
" return pd.Series(x).describe()\n",
"\n",
"\n",
"def rolling_mean(s, window=3000):\n",
" return s.rolling(window, center=True, min_periods=0).mean()\n",
"\n",
"\n",
"__all__ = ['np', 'pd', 'array', 'DataFrame', 'Series', 'plt', 'os', 'save_fig',\n",
" 'tqdm_notebook', 'tqdm', 'new_plot', 'plot', 'figure', 'scatter',\n",
" 'sys', 'array', 'DataFrame', 'Series', 'describe', 'scipy',\n",
" 'datetime', 'sklearn', 'json', 'operator', 'collections',\n",
" 'set_trace', 'random', 'time', 'arrow', 'rolling_mean', 'THOUSAND',\n",
" 'MILLION', 'BILLION']\n"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.5"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment