diff --git a/.DS_Store b/.DS_Store
index 57a9637..958d2ac 100644
Binary files a/.DS_Store and b/.DS_Store differ
diff --git a/swenao24/Day1_ERMAnimation.ipynb b/swenao24/Day1_ERMAnimation.ipynb
new file mode 100644
index 0000000..386a941
--- /dev/null
+++ b/swenao24/Day1_ERMAnimation.ipynb
@@ -0,0 +1,14557 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "%matplotlib inline\n",
+ "from matplotlib.animation import FuncAnimation\n",
+ "from IPython.display import HTML\n",
+ "import numpy as np\n",
+ "import matplotlib.pyplot as plt\n",
+ "import numpy as np\n",
+ "import matplotlib.pyplot as plt"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "The first (and probably the main) component of Machine Learning is data. Let us generate some artificial (synthetic) data. "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Step 1: Generate synthetic data\n",
+ "np.random.seed(0)\n",
+ "x = 2 * np.random.rand(100, 1)\n",
+ "y = 4 + 3 * x + np.random.randn(100, 1)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "The second component of Machine Learning is a model, i.e., a (typically very large) set of hypothesis maps. Some widely used ML models are parametrized, i.e., each hypothesis map is fully determined by a finite list of parameters. The example below defines a model that is parameterized by two numbers: `m` and `b` "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 10,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Step 2: Hypothesis function\n",
+ "def hypothesis(x, m, b):\n",
+ " return m * x + b"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "The third component of Machine Learning is a loss function which evaluates the usefulness of the predictions delivered by a hypothesis map when applied to some data point. One prominent example for a loss function, implemented below, is the squared error loss. "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 20,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Step 3: Compute cost function\n",
+ "def compute_cost(m, b, x, y):\n",
+ " return ((hypothesis(x, m, b) - y)**2).mean() / 2"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Most machine learning methods use iterative optimization methods to optimize/find/learn model parameters (which select a hypothesis map) that result in a minimum average loss on a training set. Probably the most popular class of iteration optimization methods is obtained by variations of the basic gradient descent step. "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 14,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Step 4: Initialize parameters for gradient descent\n",
+ "m_init = 0\n",
+ "b_init = 0\n",
+ "learning_rate = 0.1\n",
+ "iterations = 30\n",
+ "\n",
+ "# Gradient descent function\n",
+ "def gradient_descent(x, y, m, b, learning_rate):\n",
+ " N = len(y)\n",
+ " y_pred = hypothesis(x, m, b)\n",
+ " m_grad = (1/N) * np.sum((y_pred - y) * x)\n",
+ " b_grad = (1/N) * np.sum(y_pred - y)\n",
+ " m -= learning_rate * m_grad\n",
+ " b -= learning_rate * b_grad\n",
+ " return m, b\n",
+ "\n",
+ "# update function\n",
+ "def update(i):\n",
+ " global m_init, b_init\n",
+ " m_init, b_init = gradient_descent(x, y, m_init, b_init, learning_rate)\n",
+ " line.set_ydata(hypothesis(x, m_init, b_init))\n",
+ " title_text.set_text(f'Iteration {i+1}/{iterations}\\nLoss: {compute_cost(m_init, b_init, x, y):.4f}')\n",
+ " return line, title_text\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "The code snippet below depicts the evolution of model parameter during the execution of gradient descent steps. "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 16,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "application/javascript": [
+ "/* Put everything inside the global mpl namespace */\n",
+ "/* global mpl */\n",
+ "window.mpl = {};\n",
+ "\n",
+ "mpl.get_websocket_type = function () {\n",
+ " if (typeof WebSocket !== 'undefined') {\n",
+ " return WebSocket;\n",
+ " } else if (typeof MozWebSocket !== 'undefined') {\n",
+ " return MozWebSocket;\n",
+ " } else {\n",
+ " alert(\n",
+ " '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",
+ "\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 = document.createElement('div');\n",
+ " this.root.setAttribute('style', 'display: inline-block');\n",
+ " this._root_extra_style(this.root);\n",
+ "\n",
+ " parent_element.appendChild(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 (fig.ratio !== 1) {\n",
+ " fig.send_message('set_device_pixel_ratio', {\n",
+ " device_pixel_ratio: fig.ratio,\n",
+ " });\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 = document.createElement('div');\n",
+ " titlebar.classList =\n",
+ " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+ " var titletext = document.createElement('div');\n",
+ " titletext.classList = 'ui-dialog-title';\n",
+ " titletext.setAttribute(\n",
+ " 'style',\n",
+ " 'width: 100%; text-align: center; padding: 3px;'\n",
+ " );\n",
+ " titlebar.appendChild(titletext);\n",
+ " this.root.appendChild(titlebar);\n",
+ " this.header = titletext;\n",
+ "};\n",
+ "\n",
+ "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+ "\n",
+ "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+ "\n",
+ "mpl.figure.prototype._init_canvas = function () {\n",
+ " var fig = this;\n",
+ "\n",
+ " var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+ " canvas_div.setAttribute('tabindex', '0');\n",
+ " canvas_div.setAttribute(\n",
+ " 'style',\n",
+ " 'border: 1px solid #ddd;' +\n",
+ " 'box-sizing: content-box;' +\n",
+ " 'clear: both;' +\n",
+ " 'min-height: 1px;' +\n",
+ " 'min-width: 1px;' +\n",
+ " 'outline: 0;' +\n",
+ " 'overflow: hidden;' +\n",
+ " 'position: relative;' +\n",
+ " 'resize: both;' +\n",
+ " 'z-index: 2;'\n",
+ " );\n",
+ "\n",
+ " function on_keyboard_event_closure(name) {\n",
+ " return function (event) {\n",
+ " return fig.key_event(event, name);\n",
+ " };\n",
+ " }\n",
+ "\n",
+ " canvas_div.addEventListener(\n",
+ " 'keydown',\n",
+ " on_keyboard_event_closure('key_press')\n",
+ " );\n",
+ " canvas_div.addEventListener(\n",
+ " 'keyup',\n",
+ " on_keyboard_event_closure('key_release')\n",
+ " );\n",
+ "\n",
+ " this._canvas_extra_style(canvas_div);\n",
+ " this.root.appendChild(canvas_div);\n",
+ "\n",
+ " var canvas = (this.canvas = document.createElement('canvas'));\n",
+ " canvas.classList.add('mpl-canvas');\n",
+ " canvas.setAttribute(\n",
+ " 'style',\n",
+ " 'box-sizing: content-box;' +\n",
+ " 'pointer-events: none;' +\n",
+ " 'position: relative;' +\n",
+ " 'z-index: 0;'\n",
+ " );\n",
+ "\n",
+ " this.context = canvas.getContext('2d');\n",
+ "\n",
+ " var backingStore =\n",
+ " this.context.backingStorePixelRatio ||\n",
+ " this.context.webkitBackingStorePixelRatio ||\n",
+ " this.context.mozBackingStorePixelRatio ||\n",
+ " this.context.msBackingStorePixelRatio ||\n",
+ " this.context.oBackingStorePixelRatio ||\n",
+ " this.context.backingStorePixelRatio ||\n",
+ " 1;\n",
+ "\n",
+ " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+ "\n",
+ " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+ " 'canvas'\n",
+ " ));\n",
+ " rubberband_canvas.setAttribute(\n",
+ " 'style',\n",
+ " 'box-sizing: content-box;' +\n",
+ " 'left: 0;' +\n",
+ " 'pointer-events: none;' +\n",
+ " 'position: absolute;' +\n",
+ " 'top: 0;' +\n",
+ " 'z-index: 1;'\n",
+ " );\n",
+ "\n",
+ " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+ " if (this.ResizeObserver === undefined) {\n",
+ " if (window.ResizeObserver !== undefined) {\n",
+ " this.ResizeObserver = window.ResizeObserver;\n",
+ " } else {\n",
+ " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+ " this.ResizeObserver = obs.ResizeObserver;\n",
+ " }\n",
+ " }\n",
+ "\n",
+ " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+ " var nentries = entries.length;\n",
+ " for (var i = 0; i < nentries; i++) {\n",
+ " var entry = entries[i];\n",
+ " var width, height;\n",
+ " if (entry.contentBoxSize) {\n",
+ " if (entry.contentBoxSize instanceof Array) {\n",
+ " // Chrome 84 implements new version of spec.\n",
+ " width = entry.contentBoxSize[0].inlineSize;\n",
+ " height = entry.contentBoxSize[0].blockSize;\n",
+ " } else {\n",
+ " // Firefox implements old version of spec.\n",
+ " width = entry.contentBoxSize.inlineSize;\n",
+ " height = entry.contentBoxSize.blockSize;\n",
+ " }\n",
+ " } else {\n",
+ " // Chrome <84 implements even older version of spec.\n",
+ " width = entry.contentRect.width;\n",
+ " height = entry.contentRect.height;\n",
+ " }\n",
+ "\n",
+ " // Keep the size of the canvas and rubber band canvas in sync with\n",
+ " // the canvas container.\n",
+ " if (entry.devicePixelContentBoxSize) {\n",
+ " // Chrome 84 implements new version of spec.\n",
+ " canvas.setAttribute(\n",
+ " 'width',\n",
+ " entry.devicePixelContentBoxSize[0].inlineSize\n",
+ " );\n",
+ " canvas.setAttribute(\n",
+ " 'height',\n",
+ " entry.devicePixelContentBoxSize[0].blockSize\n",
+ " );\n",
+ " } else {\n",
+ " canvas.setAttribute('width', width * fig.ratio);\n",
+ " canvas.setAttribute('height', height * fig.ratio);\n",
+ " }\n",
+ " /* This rescales the canvas back to display pixels, so that it\n",
+ " * appears correct on HiDPI screens. */\n",
+ " canvas.style.width = width + 'px';\n",
+ " canvas.style.height = height + 'px';\n",
+ "\n",
+ " rubberband_canvas.setAttribute('width', width);\n",
+ " rubberband_canvas.setAttribute('height', height);\n",
+ "\n",
+ " // And update the size in Python. We ignore the initial 0/0 size\n",
+ " // that occurs as the element is placed into the DOM, which should\n",
+ " // otherwise not happen due to the minimum size styling.\n",
+ " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+ " fig.request_resize(width, height);\n",
+ " }\n",
+ " }\n",
+ " });\n",
+ " this.resizeObserverInstance.observe(canvas_div);\n",
+ "\n",
+ " function on_mouse_event_closure(name) {\n",
+ " /* User Agent sniffing is bad, but WebKit is busted:\n",
+ " * https://bugs.webkit.org/show_bug.cgi?id=144526\n",
+ " * https://bugs.webkit.org/show_bug.cgi?id=181818\n",
+ " * The worst that happens here is that they get an extra browser\n",
+ " * selection when dragging, if this check fails to catch them.\n",
+ " */\n",
+ " var UA = navigator.userAgent;\n",
+ " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n",
+ " if(isWebKit) {\n",
+ " return function (event) {\n",
+ " /* This prevents the web browser from automatically changing to\n",
+ " * the text insertion cursor when the button is pressed. We\n",
+ " * want to control all of the cursor setting manually through\n",
+ " * the 'cursor' event from matplotlib */\n",
+ " event.preventDefault()\n",
+ " return fig.mouse_event(event, name);\n",
+ " };\n",
+ " } else {\n",
+ " return function (event) {\n",
+ " return fig.mouse_event(event, name);\n",
+ " };\n",
+ " }\n",
+ " }\n",
+ "\n",
+ " canvas_div.addEventListener(\n",
+ " 'mousedown',\n",
+ " on_mouse_event_closure('button_press')\n",
+ " );\n",
+ " canvas_div.addEventListener(\n",
+ " 'mouseup',\n",
+ " on_mouse_event_closure('button_release')\n",
+ " );\n",
+ " canvas_div.addEventListener(\n",
+ " 'dblclick',\n",
+ " on_mouse_event_closure('dblclick')\n",
+ " );\n",
+ " // Throttle sequential mouse events to 1 every 20ms.\n",
+ " canvas_div.addEventListener(\n",
+ " 'mousemove',\n",
+ " on_mouse_event_closure('motion_notify')\n",
+ " );\n",
+ "\n",
+ " canvas_div.addEventListener(\n",
+ " 'mouseenter',\n",
+ " on_mouse_event_closure('figure_enter')\n",
+ " );\n",
+ " canvas_div.addEventListener(\n",
+ " 'mouseleave',\n",
+ " on_mouse_event_closure('figure_leave')\n",
+ " );\n",
+ "\n",
+ " canvas_div.addEventListener('wheel', function (event) {\n",
+ " if (event.deltaY < 0) {\n",
+ " event.step = 1;\n",
+ " } else {\n",
+ " event.step = -1;\n",
+ " }\n",
+ " on_mouse_event_closure('scroll')(event);\n",
+ " });\n",
+ "\n",
+ " canvas_div.appendChild(canvas);\n",
+ " canvas_div.appendChild(rubberband_canvas);\n",
+ "\n",
+ " this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+ " this.rubberband_context.strokeStyle = '#000000';\n",
+ "\n",
+ " this._resize_canvas = function (width, height, forward) {\n",
+ " if (forward) {\n",
+ " canvas_div.style.width = width + 'px';\n",
+ " canvas_div.style.height = height + 'px';\n",
+ " }\n",
+ " };\n",
+ "\n",
+ " // Disable right mouse context menu.\n",
+ " canvas_div.addEventListener('contextmenu', function (_e) {\n",
+ " event.preventDefault();\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 toolbar = document.createElement('div');\n",
+ " toolbar.classList = 'mpl-toolbar';\n",
+ " this.root.appendChild(toolbar);\n",
+ "\n",
+ " function on_click_closure(name) {\n",
+ " return function (_event) {\n",
+ " return fig.toolbar_button_onclick(name);\n",
+ " };\n",
+ " }\n",
+ "\n",
+ " function on_mouseover_closure(tooltip) {\n",
+ " return function (event) {\n",
+ " if (!event.currentTarget.disabled) {\n",
+ " return fig.toolbar_button_onmouseover(tooltip);\n",
+ " }\n",
+ " };\n",
+ " }\n",
+ "\n",
+ " fig.buttons = {};\n",
+ " var buttonGroup = document.createElement('div');\n",
+ " buttonGroup.classList = 'mpl-button-group';\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",
+ " /* Instead of a spacer, we start a new button group. */\n",
+ " if (buttonGroup.hasChildNodes()) {\n",
+ " toolbar.appendChild(buttonGroup);\n",
+ " }\n",
+ " buttonGroup = document.createElement('div');\n",
+ " buttonGroup.classList = 'mpl-button-group';\n",
+ " continue;\n",
+ " }\n",
+ "\n",
+ " var button = (fig.buttons[name] = document.createElement('button'));\n",
+ " button.classList = 'mpl-widget';\n",
+ " button.setAttribute('role', 'button');\n",
+ " button.setAttribute('aria-disabled', 'false');\n",
+ " button.addEventListener('click', on_click_closure(method_name));\n",
+ " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+ "\n",
+ " var icon_img = document.createElement('img');\n",
+ " icon_img.src = '_images/' + image + '.png';\n",
+ " icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+ " icon_img.alt = tooltip;\n",
+ " button.appendChild(icon_img);\n",
+ "\n",
+ " buttonGroup.appendChild(button);\n",
+ " }\n",
+ "\n",
+ " if (buttonGroup.hasChildNodes()) {\n",
+ " toolbar.appendChild(buttonGroup);\n",
+ " }\n",
+ "\n",
+ " var fmt_picker = document.createElement('select');\n",
+ " fmt_picker.classList = 'mpl-widget';\n",
+ " toolbar.appendChild(fmt_picker);\n",
+ " this.format_dropdown = fmt_picker;\n",
+ "\n",
+ " for (var ind in mpl.extensions) {\n",
+ " var fmt = mpl.extensions[ind];\n",
+ " var option = document.createElement('option');\n",
+ " option.selected = fmt === mpl.default_extension;\n",
+ " option.innerHTML = fmt;\n",
+ " fmt_picker.appendChild(option);\n",
+ " }\n",
+ "\n",
+ " var status_bar = document.createElement('span');\n",
+ " status_bar.classList = 'mpl-message';\n",
+ " toolbar.appendChild(status_bar);\n",
+ " this.message = status_bar;\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",
+ "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",
+ "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], msg['forward']);\n",
+ " fig.send_message('refresh', {});\n",
+ " }\n",
+ "};\n",
+ "\n",
+ "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+ " var x0 = msg['x0'] / fig.ratio;\n",
+ " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+ " var x1 = msg['x1'] / fig.ratio;\n",
+ " var y1 = (fig.canvas.height - msg['y1']) / fig.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,\n",
+ " 0,\n",
+ " fig.canvas.width / fig.ratio,\n",
+ " fig.canvas.height / fig.ratio\n",
+ " );\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",
+ " fig.canvas_div.style.cursor = msg['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.handle_history_buttons = function (fig, msg) {\n",
+ " for (var key in msg) {\n",
+ " if (!(key in fig.buttons)) {\n",
+ " continue;\n",
+ " }\n",
+ " fig.buttons[key].disabled = !msg[key];\n",
+ " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+ " }\n",
+ "};\n",
+ "\n",
+ "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+ " if (msg['mode'] === 'PAN') {\n",
+ " fig.buttons['Pan'].classList.add('active');\n",
+ " fig.buttons['Zoom'].classList.remove('active');\n",
+ " } else if (msg['mode'] === 'ZOOM') {\n",
+ " fig.buttons['Pan'].classList.remove('active');\n",
+ " fig.buttons['Zoom'].classList.add('active');\n",
+ " } else {\n",
+ " fig.buttons['Pan'].classList.remove('active');\n",
+ " fig.buttons['Zoom'].classList.remove('active');\n",
+ " }\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",
+ " var img = evt.data;\n",
+ " if (img.type !== 'image/png') {\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",
+ " img.type = 'image/png';\n",
+ " }\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",
+ "\n",
+ " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+ " img\n",
+ " );\n",
+ " fig.updated_canvas_event();\n",
+ " fig.waiting = false;\n",
+ " return;\n",
+ " } else if (\n",
+ " typeof evt.data === 'string' &&\n",
+ " evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+ " ) {\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(\n",
+ " \"No handler for the '\" + msg_type + \"' message type: \",\n",
+ " msg\n",
+ " );\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(\n",
+ " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+ " e,\n",
+ " e.stack,\n",
+ " msg\n",
+ " );\n",
+ " }\n",
+ " }\n",
+ " };\n",
+ "};\n",
+ "\n",
+ "function getModifiers(event) {\n",
+ " var mods = [];\n",
+ " if (event.ctrlKey) {\n",
+ " mods.push('ctrl');\n",
+ " }\n",
+ " if (event.altKey) {\n",
+ " mods.push('alt');\n",
+ " }\n",
+ " if (event.shiftKey) {\n",
+ " mods.push('shift');\n",
+ " }\n",
+ " if (event.metaKey) {\n",
+ " mods.push('meta');\n",
+ " }\n",
+ " return mods;\n",
+ "}\n",
+ "\n",
+ "/*\n",
+ " * return a copy of an object with only non-object keys\n",
+ " * we need this to avoid circular references\n",
+ " * https://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",
+ " }\n",
+ " return obj;\n",
+ " }, {});\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+ " if (name === 'button_press') {\n",
+ " this.canvas.focus();\n",
+ " this.canvas_div.focus();\n",
+ " }\n",
+ "\n",
+ " // from https://stackoverflow.com/q/1114465\n",
+ " var boundingRect = this.canvas.getBoundingClientRect();\n",
+ " var x = (event.clientX - boundingRect.left) * this.ratio;\n",
+ " var y = (event.clientY - boundingRect.top) * this.ratio;\n",
+ "\n",
+ " this.send_message(name, {\n",
+ " x: x,\n",
+ " y: y,\n",
+ " button: event.button,\n",
+ " step: event.step,\n",
+ " modifiers: getModifiers(event),\n",
+ " guiEvent: simpleKeys(event),\n",
+ " });\n",
+ "\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",
+ " // Prevent repeat events\n",
+ " if (name === 'key_press') {\n",
+ " if (event.key === this._key) {\n",
+ " return;\n",
+ " } else {\n",
+ " this._key = event.key;\n",
+ " }\n",
+ " }\n",
+ " if (name === 'key_release') {\n",
+ " this._key = null;\n",
+ " }\n",
+ "\n",
+ " var value = '';\n",
+ " if (event.ctrlKey && event.key !== 'Control') {\n",
+ " value += 'ctrl+';\n",
+ " }\n",
+ " else if (event.altKey && event.key !== 'Alt') {\n",
+ " value += 'alt+';\n",
+ " }\n",
+ " else if (event.shiftKey && event.key !== 'Shift') {\n",
+ " value += 'shift+';\n",
+ " }\n",
+ "\n",
+ " value += 'k' + event.key;\n",
+ "\n",
+ " this._key_event_extra(event, name);\n",
+ "\n",
+ " this.send_message(name, { key: value, 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",
+ "\n",
+ "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+ "// prettier-ignore\n",
+ "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+ "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n",
+ "\n",
+ "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n",
+ "\n",
+ "mpl.default_extension = \"png\";/* global mpl */\n",
+ "\n",
+ "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.binaryType = comm.kernel.ws.binaryType;\n",
+ " ws.readyState = comm.kernel.ws.readyState;\n",
+ " function updateReadyState(_event) {\n",
+ " if (comm.kernel.ws) {\n",
+ " ws.readyState = comm.kernel.ws.readyState;\n",
+ " } else {\n",
+ " ws.readyState = 3; // Closed state.\n",
+ " }\n",
+ " }\n",
+ " comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+ " comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+ " comm.kernel.ws.addEventListener('error', updateReadyState);\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",
+ " var data = msg['content']['data'];\n",
+ " if (data['blob'] !== undefined) {\n",
+ " data = {\n",
+ " data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+ " };\n",
+ " }\n",
+ " // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+ " ws.onmessage(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 = document.getElementById(id);\n",
+ " var ws_proxy = comm_websocket_adapter(comm);\n",
+ "\n",
+ " function ondownload(figure, _format) {\n",
+ " window.open(figure.canvas.toDataURL());\n",
+ " }\n",
+ "\n",
+ " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\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;\n",
+ " fig.cell_info = mpl.find_output_cell(\"
\");\n",
+ " if (!fig.cell_info) {\n",
+ " console.error('Failed to find cell for figure', id, fig);\n",
+ " return;\n",
+ " }\n",
+ " fig.cell_info[0].output_area.element.on(\n",
+ " 'cleared',\n",
+ " { fig: fig },\n",
+ " fig._remove_fig_handler\n",
+ " );\n",
+ "};\n",
+ "\n",
+ "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+ " var width = fig.canvas.width / fig.ratio;\n",
+ " fig.cell_info[0].output_area.element.off(\n",
+ " 'cleared',\n",
+ " fig._remove_fig_handler\n",
+ " );\n",
+ " fig.resizeObserverInstance.unobserve(fig.canvas_div);\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.innerHTML =\n",
+ " '';\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 / this.ratio;\n",
+ " var dataURL = this.canvas.toDataURL();\n",
+ " this.cell_info[1]['text/html'] =\n",
+ " '';\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 () {\n",
+ " fig.push_to_output();\n",
+ " }, 1000);\n",
+ "};\n",
+ "\n",
+ "mpl.figure.prototype._init_toolbar = function () {\n",
+ " var fig = this;\n",
+ "\n",
+ " var toolbar = document.createElement('div');\n",
+ " toolbar.classList = 'btn-toolbar';\n",
+ " this.root.appendChild(toolbar);\n",
+ "\n",
+ " function on_click_closure(name) {\n",
+ " return function (_event) {\n",
+ " return fig.toolbar_button_onclick(name);\n",
+ " };\n",
+ " }\n",
+ "\n",
+ " function on_mouseover_closure(tooltip) {\n",
+ " return function (event) {\n",
+ " if (!event.currentTarget.disabled) {\n",
+ " return fig.toolbar_button_onmouseover(tooltip);\n",
+ " }\n",
+ " };\n",
+ " }\n",
+ "\n",
+ " fig.buttons = {};\n",
+ " var buttonGroup = document.createElement('div');\n",
+ " buttonGroup.classList = 'btn-group';\n",
+ " var button;\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",
+ " /* Instead of a spacer, we start a new button group. */\n",
+ " if (buttonGroup.hasChildNodes()) {\n",
+ " toolbar.appendChild(buttonGroup);\n",
+ " }\n",
+ " buttonGroup = document.createElement('div');\n",
+ " buttonGroup.classList = 'btn-group';\n",
+ " continue;\n",
+ " }\n",
+ "\n",
+ " button = fig.buttons[name] = document.createElement('button');\n",
+ " button.classList = 'btn btn-default';\n",
+ " button.href = '#';\n",
+ " button.title = name;\n",
+ " button.innerHTML = '';\n",
+ " button.addEventListener('click', on_click_closure(method_name));\n",
+ " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+ " buttonGroup.appendChild(button);\n",
+ " }\n",
+ "\n",
+ " if (buttonGroup.hasChildNodes()) {\n",
+ " toolbar.appendChild(buttonGroup);\n",
+ " }\n",
+ "\n",
+ " // Add the status bar.\n",
+ " var status_bar = document.createElement('span');\n",
+ " status_bar.classList = 'mpl-message pull-right';\n",
+ " toolbar.appendChild(status_bar);\n",
+ " this.message = status_bar;\n",
+ "\n",
+ " // Add the close button to the window.\n",
+ " var buttongrp = document.createElement('div');\n",
+ " buttongrp.classList = 'btn-group inline pull-right';\n",
+ " button = document.createElement('button');\n",
+ " button.classList = 'btn btn-mini btn-primary';\n",
+ " button.href = '#';\n",
+ " button.title = 'Stop Interaction';\n",
+ " button.innerHTML = '';\n",
+ " button.addEventListener('click', function (_evt) {\n",
+ " fig.handle_close(fig, {});\n",
+ " });\n",
+ " button.addEventListener(\n",
+ " 'mouseover',\n",
+ " on_mouseover_closure('Stop Interaction')\n",
+ " );\n",
+ " buttongrp.appendChild(button);\n",
+ " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+ " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+ "};\n",
+ "\n",
+ "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+ " var fig = event.data.fig;\n",
+ " if (event.target !== this) {\n",
+ " // Ignore bubbled events from children.\n",
+ " return;\n",
+ " }\n",
+ " fig.close_ws(fig, {});\n",
+ "};\n",
+ "\n",
+ "mpl.figure.prototype._root_extra_style = function (el) {\n",
+ " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+ "};\n",
+ "\n",
+ "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+ " // this is important to make the div 'focusable\n",
+ " el.setAttribute('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",
+ " } else {\n",
+ " // location in version 2\n",
+ " IPython.keyboard_manager.register_events(el);\n",
+ " }\n",
+ "};\n",
+ "\n",
+ "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+ " // Check for shift+enter\n",
+ " if (event.shiftKey && event.which === 13) {\n",
+ " this.canvas_div.blur();\n",
+ " // select the cell after this one\n",
+ " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+ " IPython.notebook.select(index + 1);\n",
+ " }\n",
+ "};\n",
+ "\n",
+ "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+ " fig.ondownload(fig, null);\n",
+ "};\n",
+ "\n",
+ "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(\n",
+ " 'matplotlib',\n",
+ " mpl.mpl_figure_comm\n",
+ " );\n",
+ "}\n"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ ""
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/javascript": [
+ "/* Put everything inside the global mpl namespace */\n",
+ "/* global mpl */\n",
+ "window.mpl = {};\n",
+ "\n",
+ "mpl.get_websocket_type = function () {\n",
+ " if (typeof WebSocket !== 'undefined') {\n",
+ " return WebSocket;\n",
+ " } else if (typeof MozWebSocket !== 'undefined') {\n",
+ " return MozWebSocket;\n",
+ " } else {\n",
+ " alert(\n",
+ " '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",
+ "\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 = document.createElement('div');\n",
+ " this.root.setAttribute('style', 'display: inline-block');\n",
+ " this._root_extra_style(this.root);\n",
+ "\n",
+ " parent_element.appendChild(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 (fig.ratio !== 1) {\n",
+ " fig.send_message('set_device_pixel_ratio', {\n",
+ " device_pixel_ratio: fig.ratio,\n",
+ " });\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 = document.createElement('div');\n",
+ " titlebar.classList =\n",
+ " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+ " var titletext = document.createElement('div');\n",
+ " titletext.classList = 'ui-dialog-title';\n",
+ " titletext.setAttribute(\n",
+ " 'style',\n",
+ " 'width: 100%; text-align: center; padding: 3px;'\n",
+ " );\n",
+ " titlebar.appendChild(titletext);\n",
+ " this.root.appendChild(titlebar);\n",
+ " this.header = titletext;\n",
+ "};\n",
+ "\n",
+ "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+ "\n",
+ "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+ "\n",
+ "mpl.figure.prototype._init_canvas = function () {\n",
+ " var fig = this;\n",
+ "\n",
+ " var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+ " canvas_div.setAttribute('tabindex', '0');\n",
+ " canvas_div.setAttribute(\n",
+ " 'style',\n",
+ " 'border: 1px solid #ddd;' +\n",
+ " 'box-sizing: content-box;' +\n",
+ " 'clear: both;' +\n",
+ " 'min-height: 1px;' +\n",
+ " 'min-width: 1px;' +\n",
+ " 'outline: 0;' +\n",
+ " 'overflow: hidden;' +\n",
+ " 'position: relative;' +\n",
+ " 'resize: both;' +\n",
+ " 'z-index: 2;'\n",
+ " );\n",
+ "\n",
+ " function on_keyboard_event_closure(name) {\n",
+ " return function (event) {\n",
+ " return fig.key_event(event, name);\n",
+ " };\n",
+ " }\n",
+ "\n",
+ " canvas_div.addEventListener(\n",
+ " 'keydown',\n",
+ " on_keyboard_event_closure('key_press')\n",
+ " );\n",
+ " canvas_div.addEventListener(\n",
+ " 'keyup',\n",
+ " on_keyboard_event_closure('key_release')\n",
+ " );\n",
+ "\n",
+ " this._canvas_extra_style(canvas_div);\n",
+ " this.root.appendChild(canvas_div);\n",
+ "\n",
+ " var canvas = (this.canvas = document.createElement('canvas'));\n",
+ " canvas.classList.add('mpl-canvas');\n",
+ " canvas.setAttribute(\n",
+ " 'style',\n",
+ " 'box-sizing: content-box;' +\n",
+ " 'pointer-events: none;' +\n",
+ " 'position: relative;' +\n",
+ " 'z-index: 0;'\n",
+ " );\n",
+ "\n",
+ " this.context = canvas.getContext('2d');\n",
+ "\n",
+ " var backingStore =\n",
+ " this.context.backingStorePixelRatio ||\n",
+ " this.context.webkitBackingStorePixelRatio ||\n",
+ " this.context.mozBackingStorePixelRatio ||\n",
+ " this.context.msBackingStorePixelRatio ||\n",
+ " this.context.oBackingStorePixelRatio ||\n",
+ " this.context.backingStorePixelRatio ||\n",
+ " 1;\n",
+ "\n",
+ " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+ "\n",
+ " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+ " 'canvas'\n",
+ " ));\n",
+ " rubberband_canvas.setAttribute(\n",
+ " 'style',\n",
+ " 'box-sizing: content-box;' +\n",
+ " 'left: 0;' +\n",
+ " 'pointer-events: none;' +\n",
+ " 'position: absolute;' +\n",
+ " 'top: 0;' +\n",
+ " 'z-index: 1;'\n",
+ " );\n",
+ "\n",
+ " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+ " if (this.ResizeObserver === undefined) {\n",
+ " if (window.ResizeObserver !== undefined) {\n",
+ " this.ResizeObserver = window.ResizeObserver;\n",
+ " } else {\n",
+ " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+ " this.ResizeObserver = obs.ResizeObserver;\n",
+ " }\n",
+ " }\n",
+ "\n",
+ " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+ " var nentries = entries.length;\n",
+ " for (var i = 0; i < nentries; i++) {\n",
+ " var entry = entries[i];\n",
+ " var width, height;\n",
+ " if (entry.contentBoxSize) {\n",
+ " if (entry.contentBoxSize instanceof Array) {\n",
+ " // Chrome 84 implements new version of spec.\n",
+ " width = entry.contentBoxSize[0].inlineSize;\n",
+ " height = entry.contentBoxSize[0].blockSize;\n",
+ " } else {\n",
+ " // Firefox implements old version of spec.\n",
+ " width = entry.contentBoxSize.inlineSize;\n",
+ " height = entry.contentBoxSize.blockSize;\n",
+ " }\n",
+ " } else {\n",
+ " // Chrome <84 implements even older version of spec.\n",
+ " width = entry.contentRect.width;\n",
+ " height = entry.contentRect.height;\n",
+ " }\n",
+ "\n",
+ " // Keep the size of the canvas and rubber band canvas in sync with\n",
+ " // the canvas container.\n",
+ " if (entry.devicePixelContentBoxSize) {\n",
+ " // Chrome 84 implements new version of spec.\n",
+ " canvas.setAttribute(\n",
+ " 'width',\n",
+ " entry.devicePixelContentBoxSize[0].inlineSize\n",
+ " );\n",
+ " canvas.setAttribute(\n",
+ " 'height',\n",
+ " entry.devicePixelContentBoxSize[0].blockSize\n",
+ " );\n",
+ " } else {\n",
+ " canvas.setAttribute('width', width * fig.ratio);\n",
+ " canvas.setAttribute('height', height * fig.ratio);\n",
+ " }\n",
+ " /* This rescales the canvas back to display pixels, so that it\n",
+ " * appears correct on HiDPI screens. */\n",
+ " canvas.style.width = width + 'px';\n",
+ " canvas.style.height = height + 'px';\n",
+ "\n",
+ " rubberband_canvas.setAttribute('width', width);\n",
+ " rubberband_canvas.setAttribute('height', height);\n",
+ "\n",
+ " // And update the size in Python. We ignore the initial 0/0 size\n",
+ " // that occurs as the element is placed into the DOM, which should\n",
+ " // otherwise not happen due to the minimum size styling.\n",
+ " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+ " fig.request_resize(width, height);\n",
+ " }\n",
+ " }\n",
+ " });\n",
+ " this.resizeObserverInstance.observe(canvas_div);\n",
+ "\n",
+ " function on_mouse_event_closure(name) {\n",
+ " /* User Agent sniffing is bad, but WebKit is busted:\n",
+ " * https://bugs.webkit.org/show_bug.cgi?id=144526\n",
+ " * https://bugs.webkit.org/show_bug.cgi?id=181818\n",
+ " * The worst that happens here is that they get an extra browser\n",
+ " * selection when dragging, if this check fails to catch them.\n",
+ " */\n",
+ " var UA = navigator.userAgent;\n",
+ " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n",
+ " if(isWebKit) {\n",
+ " return function (event) {\n",
+ " /* This prevents the web browser from automatically changing to\n",
+ " * the text insertion cursor when the button is pressed. We\n",
+ " * want to control all of the cursor setting manually through\n",
+ " * the 'cursor' event from matplotlib */\n",
+ " event.preventDefault()\n",
+ " return fig.mouse_event(event, name);\n",
+ " };\n",
+ " } else {\n",
+ " return function (event) {\n",
+ " return fig.mouse_event(event, name);\n",
+ " };\n",
+ " }\n",
+ " }\n",
+ "\n",
+ " canvas_div.addEventListener(\n",
+ " 'mousedown',\n",
+ " on_mouse_event_closure('button_press')\n",
+ " );\n",
+ " canvas_div.addEventListener(\n",
+ " 'mouseup',\n",
+ " on_mouse_event_closure('button_release')\n",
+ " );\n",
+ " canvas_div.addEventListener(\n",
+ " 'dblclick',\n",
+ " on_mouse_event_closure('dblclick')\n",
+ " );\n",
+ " // Throttle sequential mouse events to 1 every 20ms.\n",
+ " canvas_div.addEventListener(\n",
+ " 'mousemove',\n",
+ " on_mouse_event_closure('motion_notify')\n",
+ " );\n",
+ "\n",
+ " canvas_div.addEventListener(\n",
+ " 'mouseenter',\n",
+ " on_mouse_event_closure('figure_enter')\n",
+ " );\n",
+ " canvas_div.addEventListener(\n",
+ " 'mouseleave',\n",
+ " on_mouse_event_closure('figure_leave')\n",
+ " );\n",
+ "\n",
+ " canvas_div.addEventListener('wheel', function (event) {\n",
+ " if (event.deltaY < 0) {\n",
+ " event.step = 1;\n",
+ " } else {\n",
+ " event.step = -1;\n",
+ " }\n",
+ " on_mouse_event_closure('scroll')(event);\n",
+ " });\n",
+ "\n",
+ " canvas_div.appendChild(canvas);\n",
+ " canvas_div.appendChild(rubberband_canvas);\n",
+ "\n",
+ " this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+ " this.rubberband_context.strokeStyle = '#000000';\n",
+ "\n",
+ " this._resize_canvas = function (width, height, forward) {\n",
+ " if (forward) {\n",
+ " canvas_div.style.width = width + 'px';\n",
+ " canvas_div.style.height = height + 'px';\n",
+ " }\n",
+ " };\n",
+ "\n",
+ " // Disable right mouse context menu.\n",
+ " canvas_div.addEventListener('contextmenu', function (_e) {\n",
+ " event.preventDefault();\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 toolbar = document.createElement('div');\n",
+ " toolbar.classList = 'mpl-toolbar';\n",
+ " this.root.appendChild(toolbar);\n",
+ "\n",
+ " function on_click_closure(name) {\n",
+ " return function (_event) {\n",
+ " return fig.toolbar_button_onclick(name);\n",
+ " };\n",
+ " }\n",
+ "\n",
+ " function on_mouseover_closure(tooltip) {\n",
+ " return function (event) {\n",
+ " if (!event.currentTarget.disabled) {\n",
+ " return fig.toolbar_button_onmouseover(tooltip);\n",
+ " }\n",
+ " };\n",
+ " }\n",
+ "\n",
+ " fig.buttons = {};\n",
+ " var buttonGroup = document.createElement('div');\n",
+ " buttonGroup.classList = 'mpl-button-group';\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",
+ " /* Instead of a spacer, we start a new button group. */\n",
+ " if (buttonGroup.hasChildNodes()) {\n",
+ " toolbar.appendChild(buttonGroup);\n",
+ " }\n",
+ " buttonGroup = document.createElement('div');\n",
+ " buttonGroup.classList = 'mpl-button-group';\n",
+ " continue;\n",
+ " }\n",
+ "\n",
+ " var button = (fig.buttons[name] = document.createElement('button'));\n",
+ " button.classList = 'mpl-widget';\n",
+ " button.setAttribute('role', 'button');\n",
+ " button.setAttribute('aria-disabled', 'false');\n",
+ " button.addEventListener('click', on_click_closure(method_name));\n",
+ " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+ "\n",
+ " var icon_img = document.createElement('img');\n",
+ " icon_img.src = '_images/' + image + '.png';\n",
+ " icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+ " icon_img.alt = tooltip;\n",
+ " button.appendChild(icon_img);\n",
+ "\n",
+ " buttonGroup.appendChild(button);\n",
+ " }\n",
+ "\n",
+ " if (buttonGroup.hasChildNodes()) {\n",
+ " toolbar.appendChild(buttonGroup);\n",
+ " }\n",
+ "\n",
+ " var fmt_picker = document.createElement('select');\n",
+ " fmt_picker.classList = 'mpl-widget';\n",
+ " toolbar.appendChild(fmt_picker);\n",
+ " this.format_dropdown = fmt_picker;\n",
+ "\n",
+ " for (var ind in mpl.extensions) {\n",
+ " var fmt = mpl.extensions[ind];\n",
+ " var option = document.createElement('option');\n",
+ " option.selected = fmt === mpl.default_extension;\n",
+ " option.innerHTML = fmt;\n",
+ " fmt_picker.appendChild(option);\n",
+ " }\n",
+ "\n",
+ " var status_bar = document.createElement('span');\n",
+ " status_bar.classList = 'mpl-message';\n",
+ " toolbar.appendChild(status_bar);\n",
+ " this.message = status_bar;\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",
+ "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",
+ "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], msg['forward']);\n",
+ " fig.send_message('refresh', {});\n",
+ " }\n",
+ "};\n",
+ "\n",
+ "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+ " var x0 = msg['x0'] / fig.ratio;\n",
+ " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+ " var x1 = msg['x1'] / fig.ratio;\n",
+ " var y1 = (fig.canvas.height - msg['y1']) / fig.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,\n",
+ " 0,\n",
+ " fig.canvas.width / fig.ratio,\n",
+ " fig.canvas.height / fig.ratio\n",
+ " );\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",
+ " fig.canvas_div.style.cursor = msg['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.handle_history_buttons = function (fig, msg) {\n",
+ " for (var key in msg) {\n",
+ " if (!(key in fig.buttons)) {\n",
+ " continue;\n",
+ " }\n",
+ " fig.buttons[key].disabled = !msg[key];\n",
+ " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+ " }\n",
+ "};\n",
+ "\n",
+ "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+ " if (msg['mode'] === 'PAN') {\n",
+ " fig.buttons['Pan'].classList.add('active');\n",
+ " fig.buttons['Zoom'].classList.remove('active');\n",
+ " } else if (msg['mode'] === 'ZOOM') {\n",
+ " fig.buttons['Pan'].classList.remove('active');\n",
+ " fig.buttons['Zoom'].classList.add('active');\n",
+ " } else {\n",
+ " fig.buttons['Pan'].classList.remove('active');\n",
+ " fig.buttons['Zoom'].classList.remove('active');\n",
+ " }\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",
+ " var img = evt.data;\n",
+ " if (img.type !== 'image/png') {\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",
+ " img.type = 'image/png';\n",
+ " }\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",
+ "\n",
+ " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+ " img\n",
+ " );\n",
+ " fig.updated_canvas_event();\n",
+ " fig.waiting = false;\n",
+ " return;\n",
+ " } else if (\n",
+ " typeof evt.data === 'string' &&\n",
+ " evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+ " ) {\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(\n",
+ " \"No handler for the '\" + msg_type + \"' message type: \",\n",
+ " msg\n",
+ " );\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(\n",
+ " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+ " e,\n",
+ " e.stack,\n",
+ " msg\n",
+ " );\n",
+ " }\n",
+ " }\n",
+ " };\n",
+ "};\n",
+ "\n",
+ "function getModifiers(event) {\n",
+ " var mods = [];\n",
+ " if (event.ctrlKey) {\n",
+ " mods.push('ctrl');\n",
+ " }\n",
+ " if (event.altKey) {\n",
+ " mods.push('alt');\n",
+ " }\n",
+ " if (event.shiftKey) {\n",
+ " mods.push('shift');\n",
+ " }\n",
+ " if (event.metaKey) {\n",
+ " mods.push('meta');\n",
+ " }\n",
+ " return mods;\n",
+ "}\n",
+ "\n",
+ "/*\n",
+ " * return a copy of an object with only non-object keys\n",
+ " * we need this to avoid circular references\n",
+ " * https://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",
+ " }\n",
+ " return obj;\n",
+ " }, {});\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+ " if (name === 'button_press') {\n",
+ " this.canvas.focus();\n",
+ " this.canvas_div.focus();\n",
+ " }\n",
+ "\n",
+ " // from https://stackoverflow.com/q/1114465\n",
+ " var boundingRect = this.canvas.getBoundingClientRect();\n",
+ " var x = (event.clientX - boundingRect.left) * this.ratio;\n",
+ " var y = (event.clientY - boundingRect.top) * this.ratio;\n",
+ "\n",
+ " this.send_message(name, {\n",
+ " x: x,\n",
+ " y: y,\n",
+ " button: event.button,\n",
+ " step: event.step,\n",
+ " modifiers: getModifiers(event),\n",
+ " guiEvent: simpleKeys(event),\n",
+ " });\n",
+ "\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",
+ " // Prevent repeat events\n",
+ " if (name === 'key_press') {\n",
+ " if (event.key === this._key) {\n",
+ " return;\n",
+ " } else {\n",
+ " this._key = event.key;\n",
+ " }\n",
+ " }\n",
+ " if (name === 'key_release') {\n",
+ " this._key = null;\n",
+ " }\n",
+ "\n",
+ " var value = '';\n",
+ " if (event.ctrlKey && event.key !== 'Control') {\n",
+ " value += 'ctrl+';\n",
+ " }\n",
+ " else if (event.altKey && event.key !== 'Alt') {\n",
+ " value += 'alt+';\n",
+ " }\n",
+ " else if (event.shiftKey && event.key !== 'Shift') {\n",
+ " value += 'shift+';\n",
+ " }\n",
+ "\n",
+ " value += 'k' + event.key;\n",
+ "\n",
+ " this._key_event_extra(event, name);\n",
+ "\n",
+ " this.send_message(name, { key: value, 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",
+ "\n",
+ "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+ "// prettier-ignore\n",
+ "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+ "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n",
+ "\n",
+ "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n",
+ "\n",
+ "mpl.default_extension = \"png\";/* global mpl */\n",
+ "\n",
+ "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.binaryType = comm.kernel.ws.binaryType;\n",
+ " ws.readyState = comm.kernel.ws.readyState;\n",
+ " function updateReadyState(_event) {\n",
+ " if (comm.kernel.ws) {\n",
+ " ws.readyState = comm.kernel.ws.readyState;\n",
+ " } else {\n",
+ " ws.readyState = 3; // Closed state.\n",
+ " }\n",
+ " }\n",
+ " comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+ " comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+ " comm.kernel.ws.addEventListener('error', updateReadyState);\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",
+ " var data = msg['content']['data'];\n",
+ " if (data['blob'] !== undefined) {\n",
+ " data = {\n",
+ " data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+ " };\n",
+ " }\n",
+ " // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+ " ws.onmessage(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 = document.getElementById(id);\n",
+ " var ws_proxy = comm_websocket_adapter(comm);\n",
+ "\n",
+ " function ondownload(figure, _format) {\n",
+ " window.open(figure.canvas.toDataURL());\n",
+ " }\n",
+ "\n",
+ " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\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;\n",
+ " fig.cell_info = mpl.find_output_cell(\"\");\n",
+ " if (!fig.cell_info) {\n",
+ " console.error('Failed to find cell for figure', id, fig);\n",
+ " return;\n",
+ " }\n",
+ " fig.cell_info[0].output_area.element.on(\n",
+ " 'cleared',\n",
+ " { fig: fig },\n",
+ " fig._remove_fig_handler\n",
+ " );\n",
+ "};\n",
+ "\n",
+ "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+ " var width = fig.canvas.width / fig.ratio;\n",
+ " fig.cell_info[0].output_area.element.off(\n",
+ " 'cleared',\n",
+ " fig._remove_fig_handler\n",
+ " );\n",
+ " fig.resizeObserverInstance.unobserve(fig.canvas_div);\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.innerHTML =\n",
+ " '';\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 / this.ratio;\n",
+ " var dataURL = this.canvas.toDataURL();\n",
+ " this.cell_info[1]['text/html'] =\n",
+ " '';\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 () {\n",
+ " fig.push_to_output();\n",
+ " }, 1000);\n",
+ "};\n",
+ "\n",
+ "mpl.figure.prototype._init_toolbar = function () {\n",
+ " var fig = this;\n",
+ "\n",
+ " var toolbar = document.createElement('div');\n",
+ " toolbar.classList = 'btn-toolbar';\n",
+ " this.root.appendChild(toolbar);\n",
+ "\n",
+ " function on_click_closure(name) {\n",
+ " return function (_event) {\n",
+ " return fig.toolbar_button_onclick(name);\n",
+ " };\n",
+ " }\n",
+ "\n",
+ " function on_mouseover_closure(tooltip) {\n",
+ " return function (event) {\n",
+ " if (!event.currentTarget.disabled) {\n",
+ " return fig.toolbar_button_onmouseover(tooltip);\n",
+ " }\n",
+ " };\n",
+ " }\n",
+ "\n",
+ " fig.buttons = {};\n",
+ " var buttonGroup = document.createElement('div');\n",
+ " buttonGroup.classList = 'btn-group';\n",
+ " var button;\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",
+ " /* Instead of a spacer, we start a new button group. */\n",
+ " if (buttonGroup.hasChildNodes()) {\n",
+ " toolbar.appendChild(buttonGroup);\n",
+ " }\n",
+ " buttonGroup = document.createElement('div');\n",
+ " buttonGroup.classList = 'btn-group';\n",
+ " continue;\n",
+ " }\n",
+ "\n",
+ " button = fig.buttons[name] = document.createElement('button');\n",
+ " button.classList = 'btn btn-default';\n",
+ " button.href = '#';\n",
+ " button.title = name;\n",
+ " button.innerHTML = '';\n",
+ " button.addEventListener('click', on_click_closure(method_name));\n",
+ " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+ " buttonGroup.appendChild(button);\n",
+ " }\n",
+ "\n",
+ " if (buttonGroup.hasChildNodes()) {\n",
+ " toolbar.appendChild(buttonGroup);\n",
+ " }\n",
+ "\n",
+ " // Add the status bar.\n",
+ " var status_bar = document.createElement('span');\n",
+ " status_bar.classList = 'mpl-message pull-right';\n",
+ " toolbar.appendChild(status_bar);\n",
+ " this.message = status_bar;\n",
+ "\n",
+ " // Add the close button to the window.\n",
+ " var buttongrp = document.createElement('div');\n",
+ " buttongrp.classList = 'btn-group inline pull-right';\n",
+ " button = document.createElement('button');\n",
+ " button.classList = 'btn btn-mini btn-primary';\n",
+ " button.href = '#';\n",
+ " button.title = 'Stop Interaction';\n",
+ " button.innerHTML = '';\n",
+ " button.addEventListener('click', function (_evt) {\n",
+ " fig.handle_close(fig, {});\n",
+ " });\n",
+ " button.addEventListener(\n",
+ " 'mouseover',\n",
+ " on_mouseover_closure('Stop Interaction')\n",
+ " );\n",
+ " buttongrp.appendChild(button);\n",
+ " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+ " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+ "};\n",
+ "\n",
+ "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+ " var fig = event.data.fig;\n",
+ " if (event.target !== this) {\n",
+ " // Ignore bubbled events from children.\n",
+ " return;\n",
+ " }\n",
+ " fig.close_ws(fig, {});\n",
+ "};\n",
+ "\n",
+ "mpl.figure.prototype._root_extra_style = function (el) {\n",
+ " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+ "};\n",
+ "\n",
+ "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+ " // this is important to make the div 'focusable\n",
+ " el.setAttribute('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",
+ " } else {\n",
+ " // location in version 2\n",
+ " IPython.keyboard_manager.register_events(el);\n",
+ " }\n",
+ "};\n",
+ "\n",
+ "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+ " // Check for shift+enter\n",
+ " if (event.shiftKey && event.which === 13) {\n",
+ " this.canvas_div.blur();\n",
+ " // select the cell after this one\n",
+ " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+ " IPython.notebook.select(index + 1);\n",
+ " }\n",
+ "};\n",
+ "\n",
+ "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+ " fig.ondownload(fig, null);\n",
+ "};\n",
+ "\n",
+ "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(\n",
+ " 'matplotlib',\n",
+ " mpl.mpl_figure_comm\n",
+ " );\n",
+ "}\n"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ ""
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "\n",
+ "\n",
+ "\n",
+ "\n",
+ "\n",
+ "
\n",
+ "
\n",
+ "
\n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ "
\n",
+ "
\n",
+ "
\n",
+ "
\n",
+ "\n",
+ "\n",
+ "\n"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "execution_count": 16,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "%matplotlib notebook\n",
+ "from IPython.display import HTML\n",
+ "from matplotlib.animation import FuncAnimation\n",
+ "import matplotlib.pyplot as plt\n",
+ "import numpy as np\n",
+ "\n",
+ "m_init = 0\n",
+ "b_init = 0\n",
+ "\n",
+ "# Code setup for data generation, hypothesis and gradient_descent remains same\n",
+ "\n",
+ "# Prepare the animation\n",
+ "fig, ax = plt.subplots()\n",
+ "ax.scatter(x, y, alpha=0.5)\n",
+ "ax.set_xlim(0, 2)\n",
+ "ax.set_ylim(y.min() - 1, y.max() + 1)\n",
+ "\n",
+ "ax.set_xlabel('x')\n",
+ "ax.set_ylabel('y')\n",
+ "title_text = ax.text(0.5, 0.95, '', transform=ax.transAxes, ha='center')\n",
+ "\n",
+ "for itergd in range(iterations): \n",
+ " m_init, b_init = gradient_descent(x, y, m_init, b_init, learning_rate)\n",
+ " \n",
+ "line, = ax.plot(x, hypothesis(x, m_init, b_init), 'r-', linewidth=2)\n",
+ "title_text.set_text(f'Iterations: {iterations} Train Error: {compute_cost(m_init, b_init, x, y):.4f}')\n",
+ "plt.show()\n",
+ "\n",
+ "\n",
+ "# Prepare the plot\n",
+ "fig, ax = plt.subplots()\n",
+ "ax.scatter(x, y, alpha=0.5)\n",
+ "line, = ax.plot(x, hypothesis(x, m_init, b_init), 'r-', linewidth=2)\n",
+ "ax.set_xlim(0, 2)\n",
+ "ax.set_ylim(y.min() - 1, y.max() + 1)\n",
+ "ax.set_xlabel('x')\n",
+ "ax.set_ylabel('y')\n",
+ "title_text = ax.text(0.5, 0.95, '', transform=ax.transAxes, ha='center')\n",
+ "\n",
+ "# Create and display animation\n",
+ "ani = FuncAnimation(fig, update, frames=iterations, repeat=False)\n",
+ "HTML(ani.to_jshtml()) # Use to_jshtml() for interactive control within the notebook\n"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "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.11.5"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}
diff --git a/swenao24/Day1_LinModelDifferentLoss.ipynb b/swenao24/Day1_LinModelDifferentLoss.ipynb
new file mode 100644
index 0000000..dfe9967
--- /dev/null
+++ b/swenao24/Day1_LinModelDifferentLoss.ipynb
@@ -0,0 +1,324 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "826ad26f-7e63-4daf-b0d5-ba7ae8ace7b2",
+ "metadata": {},
+ "source": [
+ "## Each ML method is characterized by design choices for: data representation/source, model and loss function.\n",
+ "## The code snippet below illustrates how changing the loss function, while using the same linear model, changes the statistical and computational properties of the resulting ML method."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "id": "64edf176-8a9a-46b5-8370-a837fde02061",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "LinReg Time: 0.0009250640869140625\n",
+ "HuberReg Time: 4.96 times Linreg time\n"
+ ]
+ },
+ {
+ "data": {
+ "image/png": "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wiTr3n77baNGjRop+JOKiIikb2qzRTIG9XSLZEL169fn008/TVzOli0bpUuXZu/evYwZMyZxvdVq5ebNm0RHR+Pj48OWLVt45513OHz4MJGRkcTHx3Pz5k2uX79OtmzZUl1XtWrVEn9//vx5Tp8+TZ8+fejXr1/i+vj4ePz8/FJ9LhERkfRAbbZI+qfQLZIJ3Wqw/yshIYFRo0YRHBx8x/be3t6cPHmS5s2b079/f95++21y587Nzp076dOnD3Fxccmez2KxYBhGknV32+e//whISEgAYPr06Tz55JNJtnN3d0/+DygiIpJBqM0WSf8UukUEgCpVqnD06NE7GvZb9u3bR3x8POPHj8fNzRyD8csvv0yyjaenJ1ar9Y598+XLR0REROLyr7/+SnR0dLL1FChQgMKFC/PHH3/QrVs3W/84IiIiGZbabJH0RaFbRAB48803admyJUWLFqVDhw64ubnx448/8tNPPzF69GhKlSpFfHw8kydPplWrVnzzzTdMnTo1yTFKlCjBtWvX2LRpE4899hg+Pj74+PjQoEEDPv74Y6pXr05CQgKvvPJKiqYWGTlyJIMGDcLX15dmzZoRExPDvn37uHz5MkOHDnXUpRAREXFparNF0hdNGSYiADRp0oRVq1YRHh7O448/TvXq1ZkwYQLFixcHoHLlykyYMIH33nuPihUrsmDBAsaOHZvkGDVr1qR///506tSJfPnyMW7cOADGjx9P0aJFqVOnDl27duXFF1/Ex8fnvjX17duXzz//nNmzZ1OpUiXq1q3L7NmzKVmypP0vgIiISDqhNlskfbEYt7+0ISIiIiIiIiJ2oZ5uEREREREREQdR6BYRERERERFxEIVuEREREREREQdR6BYRERERERFxEIVuEREREREREQdR6BYRERERERFxEIVuEREREREREQdR6BYRERERERFxEIVuEREREREREQdR6BYRERERERFxEIVuEREREREREQdR6BYRERERERFxkP8DgP6jbDqOo2kAAAAASUVORK5CYII=",
+ "text/plain": [
+ "