{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Basic Plotting with matplotlib"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can show matplotlib figures directly in the notebook by using the `%matplotlib notebook` and `%matplotlib inline` magic commands. \n",
    "\n",
    "`%matplotlib notebook` provides an interactive environment."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    " #show matplotlib figures directly in the notebook\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib notebook"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'nbAgg'"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import matplotlib as mpl\n",
    "mpl.get_backend()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "plt.plot?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "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_dpi_ratio', { dpi_ratio: fig.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 = 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(\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",
       "    );\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('style', 'box-sizing: content-box;');\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; position: absolute; left: 0; top: 0; 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",
       "            canvas.setAttribute(\n",
       "                'style',\n",
       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
       "            );\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",
       "        return function (event) {\n",
       "            return fig.mouse_event(event, name);\n",
       "        };\n",
       "    }\n",
       "\n",
       "    rubberband_canvas.addEventListener(\n",
       "        'mousedown',\n",
       "        on_mouse_event_closure('button_press')\n",
       "    );\n",
       "    rubberband_canvas.addEventListener(\n",
       "        'mouseup',\n",
       "        on_mouse_event_closure('button_release')\n",
       "    );\n",
       "    // Throttle sequential mouse events to 1 every 20ms.\n",
       "    rubberband_canvas.addEventListener(\n",
       "        'mousemove',\n",
       "        on_mouse_event_closure('motion_notify')\n",
       "    );\n",
       "\n",
       "    rubberband_canvas.addEventListener(\n",
       "        'mouseenter',\n",
       "        on_mouse_event_closure('figure_enter')\n",
       "    );\n",
       "    rubberband_canvas.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",
       "    this.rubberband_canvas.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",
       "    var cursor = msg['cursor'];\n",
       "    switch (cursor) {\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.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",
       "            /* 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",
       "\n",
       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
       "                evt.data\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",
       "// 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",
       "    }\n",
       "    if (e.target) {\n",
       "        targ = e.target;\n",
       "    } else if (e.srcElement) {\n",
       "        targ = e.srcElement;\n",
       "    }\n",
       "    if (targ.nodeType === 3) {\n",
       "        // defeat Safari bug\n",
       "        targ = targ.parentNode;\n",
       "    }\n",
       "\n",
       "    // pageX,Y are the mouse positions relative to the document\n",
       "    var boundingRect = targ.getBoundingClientRect();\n",
       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\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",
       "        }\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",
       "        this.canvas.focus();\n",
       "        this.canvas_div.focus();\n",
       "    }\n",
       "\n",
       "    var x = canvas_pos.x * this.ratio;\n",
       "    var y = canvas_pos.y * this.ratio;\n",
       "\n",
       "    this.send_message(name, {\n",
       "        x: x,\n",
       "        y: y,\n",
       "        button: event.button,\n",
       "        step: event.step,\n",
       "        guiEvent: simpleKeys(event),\n",
       "    });\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",
       "    // Prevent repeat events\n",
       "    if (name === 'key_press') {\n",
       "        if (event.which === this._key) {\n",
       "            return;\n",
       "        } else {\n",
       "            this._key = event.which;\n",
       "        }\n",
       "    }\n",
       "    if (name === 'key_release') {\n",
       "        this._key = null;\n",
       "    }\n",
       "\n",
       "    var value = '';\n",
       "    if (event.ctrlKey && event.which !== 17) {\n",
       "        value += 'ctrl+';\n",
       "    }\n",
       "    if (event.altKey && event.which !== 18) {\n",
       "        value += 'alt+';\n",
       "    }\n",
       "    if (event.shiftKey && event.which !== 16) {\n",
       "        value += 'shift+';\n",
       "    }\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, 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 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\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis, CTRL fixes aspect\", \"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\";/* 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.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 = 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(\"<div id='\" + id + \"'></div>\");\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",
       "        '<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 / this.ratio;\n",
       "    var dataURL = this.canvas.toDataURL();\n",
       "    this.cell_info[1]['text/html'] =\n",
       "        '<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 () {\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 = '<i class=\"fa ' + image + ' fa-lg\"></i>';\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 = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\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",
       "    var manager = IPython.notebook.keyboard_manager;\n",
       "    if (!manager) {\n",
       "        manager = IPython.keyboard_manager;\n",
       "    }\n",
       "\n",
       "    // Check for shift+enter\n",
       "    if (event.shiftKey && event.which === 13) {\n",
       "        this.canvas_div.blur();\n",
       "        // select the cell after this one\n",
       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
       "        IPython.notebook.select(index + 1);\n",
       "    }\n",
       "};\n",
       "\n",
       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
       "    fig.ondownload(fig, null);\n",
       "};\n",
       "\n",
       "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": [
       "<IPython.core.display.Javascript object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<img src=\"data:image/png;base64,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mZlStWpVGTFihDz//PPRMY888ohs3Ljxmtfo0KGDrF271v19RkaGjB49Ot86FSpUkGPHjgUOIwEKTMWKCCCAAAIIhEaA+TsEBXD9+vWydetWadSokXTt2vWmBXDGjBkybNgwmTNnjjRp0kR27NghvXv3lsWLF0vHjh1duL799lu5cOFCNGh/+9vf5Oc//7nMnTtXevbsGS2Ay5cvl08//TS6XtGiReXee+8NHFACFJiKFRFAAAEEEAiNAPN3CArglWlISkq6aQFs2bKltGrVyh01jCyDBg2Szz//XLZs2RIzXFOmTJFRo0a5I4ylS5eOFsBVq1bJzp07bzuQBOi26RiIAAIIIICANwHm7zgsgI0bNxY9lTtmzJhocNLT0+XNN9+UM2fOSLFixa4J1AMPPCAtWrSQ2bNnR3+mp4C1RKakpEjx4sWlWbNmMm7cOLnvvvuuG8jz58+L/oksGqC0tDTJzc2V5ORkb0HmjRFAAAEEEEAguAAFMA4L4PDhw2XevHny0UcfudPGeu3gE088ISdOnJCsrCypVKlSvgToKWItd3/84x+ladOm0Z/pqeezZ89K7dq15fjx4/L666/L/v37Zc+ePVKuXLmYKYp13aCuSAEM/qVjTQQQQAABBHwLUADjsACeO3dO+vfvL4sWLZK8vDzRGzeeffZZmThxoity5cuXz5erPn36yLZt22T37t03zJsePaxZs6YMHTpUhgwZEnNdjgD6/sry/ggggAACCNgFKIBxWAAju/2HH35whU+P+OmpXb0x5NSpU1KkSJFoMvQIn/78tddek4EDB940MY899pjcf//9ojeaBFkIUBAl1kEAAQQQQCBcAszfcVwAr4xSu3btJDU11d0JfOUyf/586du3rxw9evS6p3Uj6+vRPT0C+NJLL7kbRoIsBCiIEusggAACCCAQLgHm7xAUwO+++04OHTrkktGwYUN566235NFHH5V77rnHPeNPb/DQArdw4UK3zsGDB92jX/S6vpycHLf+J5984q4FrF69er6EtWnTxhXD999//5rkvfLKK+6xMfoeev2gXgOozw7UU8XVqlULlFQCFIiJlRBAAAEEEAiVAPN3CArghg0bXOG7eunRo4foETx9bp8+8FnX02Xfvn3SvXt3OXDggLvjV8dOmDBB6tSpk+8ltCjq33388ceip3avXrp16yb6EOpvvvnG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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 0x24b119fd9d0>]"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "%matplotlib notebook\n",
    "\n",
    "# because the default is the line style '-', \n",
    "# nothing will be shown if we only pass in one point (3,2)\n",
    "plt.plot(3.5, 2,'*')"
   ]
  },
  {
   "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_dpi_ratio', { dpi_ratio: fig.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 = 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(\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",
       "    );\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('style', 'box-sizing: content-box;');\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; position: absolute; left: 0; top: 0; 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",
       "            canvas.setAttribute(\n",
       "                'style',\n",
       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
       "            );\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",
       "        return function (event) {\n",
       "            return fig.mouse_event(event, name);\n",
       "        };\n",
       "    }\n",
       "\n",
       "    rubberband_canvas.addEventListener(\n",
       "        'mousedown',\n",
       "        on_mouse_event_closure('button_press')\n",
       "    );\n",
       "    rubberband_canvas.addEventListener(\n",
       "        'mouseup',\n",
       "        on_mouse_event_closure('button_release')\n",
       "    );\n",
       "    // Throttle sequential mouse events to 1 every 20ms.\n",
       "    rubberband_canvas.addEventListener(\n",
       "        'mousemove',\n",
       "        on_mouse_event_closure('motion_notify')\n",
       "    );\n",
       "\n",
       "    rubberband_canvas.addEventListener(\n",
       "        'mouseenter',\n",
       "        on_mouse_event_closure('figure_enter')\n",
       "    );\n",
       "    rubberband_canvas.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",
       "    this.rubberband_canvas.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",
       "    var cursor = msg['cursor'];\n",
       "    switch (cursor) {\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.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",
       "            /* 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",
       "\n",
       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
       "                evt.data\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",
       "// 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",
       "    }\n",
       "    if (e.target) {\n",
       "        targ = e.target;\n",
       "    } else if (e.srcElement) {\n",
       "        targ = e.srcElement;\n",
       "    }\n",
       "    if (targ.nodeType === 3) {\n",
       "        // defeat Safari bug\n",
       "        targ = targ.parentNode;\n",
       "    }\n",
       "\n",
       "    // pageX,Y are the mouse positions relative to the document\n",
       "    var boundingRect = targ.getBoundingClientRect();\n",
       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\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",
       "        }\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",
       "        this.canvas.focus();\n",
       "        this.canvas_div.focus();\n",
       "    }\n",
       "\n",
       "    var x = canvas_pos.x * this.ratio;\n",
       "    var y = canvas_pos.y * this.ratio;\n",
       "\n",
       "    this.send_message(name, {\n",
       "        x: x,\n",
       "        y: y,\n",
       "        button: event.button,\n",
       "        step: event.step,\n",
       "        guiEvent: simpleKeys(event),\n",
       "    });\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",
       "    // Prevent repeat events\n",
       "    if (name === 'key_press') {\n",
       "        if (event.which === this._key) {\n",
       "            return;\n",
       "        } else {\n",
       "            this._key = event.which;\n",
       "        }\n",
       "    }\n",
       "    if (name === 'key_release') {\n",
       "        this._key = null;\n",
       "    }\n",
       "\n",
       "    var value = '';\n",
       "    if (event.ctrlKey && event.which !== 17) {\n",
       "        value += 'ctrl+';\n",
       "    }\n",
       "    if (event.altKey && event.which !== 18) {\n",
       "        value += 'alt+';\n",
       "    }\n",
       "    if (event.shiftKey && event.which !== 16) {\n",
       "        value += 'shift+';\n",
       "    }\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, 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 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\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis, CTRL fixes aspect\", \"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\";/* 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.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 = 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(\"<div id='\" + id + \"'></div>\");\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",
       "        '<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 / this.ratio;\n",
       "    var dataURL = this.canvas.toDataURL();\n",
       "    this.cell_info[1]['text/html'] =\n",
       "        '<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 () {\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 = '<i class=\"fa ' + image + ' fa-lg\"></i>';\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 = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\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",
       "    var manager = IPython.notebook.keyboard_manager;\n",
       "    if (!manager) {\n",
       "        manager = IPython.keyboard_manager;\n",
       "    }\n",
       "\n",
       "    // Check for shift+enter\n",
       "    if (event.shiftKey && event.which === 13) {\n",
       "        this.canvas_div.blur();\n",
       "        // select the cell after this one\n",
       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
       "        IPython.notebook.select(index + 1);\n",
       "    }\n",
       "};\n",
       "\n",
       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
       "    fig.ondownload(fig, null);\n",
       "};\n",
       "\n",
       "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": [
       "<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 0x24b11d00eb0>]"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# we can pass in '.' to plt.plot to indicate that we want\n",
    "# the point (3,2) to be indicated with a marker '.'\n",
    "%matplotlib notebook\n",
    "plt.plot(3.5, 2, '.')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's see how to make a plot without using the scripting layer."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "%matplotlib notebook\n",
    "\n",
    "# First let's set the backend without using mpl.use() from the scripting layer\n",
    "from matplotlib.backends.backend_agg import FigureCanvasAgg\n",
    "from matplotlib.figure import Figure\n",
    "\n",
    "# create a new figure\n",
    "fig = Figure()\n",
    "\n",
    "# associate fig with the backend\n",
    "canvas = FigureCanvasAgg(fig)\n",
    "\n",
    "# add a subplot to the fig\n",
    "ax = fig.add_subplot(111)\n",
    "\n",
    "# plot the point (3,2)\n",
    "ax.plot(3, 2, '.')\n",
    "\n",
    "# save the figure to test.png\n",
    "# you can see this figure in your Jupyter workspace afterwards by going to\n",
    "# https://hub.coursera-notebooks.org/\n",
    "canvas.print_png('test.png')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can use html cell magic to display the image."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<img src='test.png' />\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "%%html\n",
    "<img src='test.png' />"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "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_dpi_ratio', { dpi_ratio: fig.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 = 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(\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",
       "    );\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('style', 'box-sizing: content-box;');\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; position: absolute; left: 0; top: 0; 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",
       "            canvas.setAttribute(\n",
       "                'style',\n",
       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
       "            );\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",
       "        return function (event) {\n",
       "            return fig.mouse_event(event, name);\n",
       "        };\n",
       "    }\n",
       "\n",
       "    rubberband_canvas.addEventListener(\n",
       "        'mousedown',\n",
       "        on_mouse_event_closure('button_press')\n",
       "    );\n",
       "    rubberband_canvas.addEventListener(\n",
       "        'mouseup',\n",
       "        on_mouse_event_closure('button_release')\n",
       "    );\n",
       "    // Throttle sequential mouse events to 1 every 20ms.\n",
       "    rubberband_canvas.addEventListener(\n",
       "        'mousemove',\n",
       "        on_mouse_event_closure('motion_notify')\n",
       "    );\n",
       "\n",
       "    rubberband_canvas.addEventListener(\n",
       "        'mouseenter',\n",
       "        on_mouse_event_closure('figure_enter')\n",
       "    );\n",
       "    rubberband_canvas.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",
       "    this.rubberband_canvas.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",
       "    var cursor = msg['cursor'];\n",
       "    switch (cursor) {\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.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",
       "            /* 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",
       "\n",
       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
       "                evt.data\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",
       "// 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",
       "    }\n",
       "    if (e.target) {\n",
       "        targ = e.target;\n",
       "    } else if (e.srcElement) {\n",
       "        targ = e.srcElement;\n",
       "    }\n",
       "    if (targ.nodeType === 3) {\n",
       "        // defeat Safari bug\n",
       "        targ = targ.parentNode;\n",
       "    }\n",
       "\n",
       "    // pageX,Y are the mouse positions relative to the document\n",
       "    var boundingRect = targ.getBoundingClientRect();\n",
       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\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",
       "        }\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",
       "        this.canvas.focus();\n",
       "        this.canvas_div.focus();\n",
       "    }\n",
       "\n",
       "    var x = canvas_pos.x * this.ratio;\n",
       "    var y = canvas_pos.y * this.ratio;\n",
       "\n",
       "    this.send_message(name, {\n",
       "        x: x,\n",
       "        y: y,\n",
       "        button: event.button,\n",
       "        step: event.step,\n",
       "        guiEvent: simpleKeys(event),\n",
       "    });\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",
       "    // Prevent repeat events\n",
       "    if (name === 'key_press') {\n",
       "        if (event.which === this._key) {\n",
       "            return;\n",
       "        } else {\n",
       "            this._key = event.which;\n",
       "        }\n",
       "    }\n",
       "    if (name === 'key_release') {\n",
       "        this._key = null;\n",
       "    }\n",
       "\n",
       "    var value = '';\n",
       "    if (event.ctrlKey && event.which !== 17) {\n",
       "        value += 'ctrl+';\n",
       "    }\n",
       "    if (event.altKey && event.which !== 18) {\n",
       "        value += 'alt+';\n",
       "    }\n",
       "    if (event.shiftKey && event.which !== 16) {\n",
       "        value += 'shift+';\n",
       "    }\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, 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 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\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis, CTRL fixes aspect\", \"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\";/* 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.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 = 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(\"<div id='\" + id + \"'></div>\");\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",
       "        '<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 / this.ratio;\n",
       "    var dataURL = this.canvas.toDataURL();\n",
       "    this.cell_info[1]['text/html'] =\n",
       "        '<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 () {\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 = '<i class=\"fa ' + image + ' fa-lg\"></i>';\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 = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\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",
       "    var manager = IPython.notebook.keyboard_manager;\n",
       "    if (!manager) {\n",
       "        manager = IPython.keyboard_manager;\n",
       "    }\n",
       "\n",
       "    // Check for shift+enter\n",
       "    if (event.shiftKey && event.which === 13) {\n",
       "        this.canvas_div.blur();\n",
       "        // select the cell after this one\n",
       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
       "        IPython.notebook.select(index + 1);\n",
       "    }\n",
       "};\n",
       "\n",
       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
       "    fig.ondownload(fig, null);\n",
       "};\n",
       "\n",
       "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": [
       "<IPython.core.display.Javascript object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<img src=\"data:image/png;base64,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vxXAVPAEKMVnmAABAgQIFBGwvxXAVPAEKMVnmAABAgQIFBGwvxXAVPAEKMVnmAABAgQIFBGwvxXAVPAEKMVnmAABAgQIFBGwvxXAVPAEKMVnmAABAgQIFBGwvxXAVPAEKMVnmAABAgQIFBGwvxXAVPAEKMVnmAABAgQIFBGwvxXAVPAEKMVnmAABAgQIFBGwvxXAVPAEKMVnmAABAgQIFBGwvxXAVPAEKMVnmAABAgQIFBGwvxXAVPAEKMVnmAABAgQIFBGwvxXAVPAEKMVnmAABAgQIFBGwvxXAVPAEKMVnmAABAgQIFBGwvxXAVPAEKMVnmAABAgQIFBGwvxXAVPAEKMVnmAABAgQIFBGwvxXAVPAEKMVnmAABAgQIFBGwvxXAVPAEKMVnmAABAgQIFBGwvxXAVPAEKMVnmAABAgQIFBGwvxXAVPAEKMVnmAABAgQIFBGwvxXAVPAEKMVnmAABAgQIFBGwvxXAVPAEKMVnmAABAgQIFBGwvxXAVPAEKMVnmAABAgQIFBGwvxXAVPAEKMVnmAABAgQIFBGwvxXAVPAEKMVnmAABAgQIFBGwvxXAVPAEKMVnmAABAgQIFBGwvxXAVPAEKMVnmAABAgQIFBGwvxXAVPAEKMVnmAABAgQIFBGwvxXAVPAEKMVnmAABAgQIFBGwvxXAVPAEKMVnmAABAgQIFBGwvxXAVPAEKMVnmAABAgQIFBGwvxXAVPAEKMVnmAABAgQIFBGwvxXAVPAEKMVnmAABAgQIFBGwvxXAVPAEKMVnmAABAgQIFBGwvxXAVPAEKMVnmAABAgQIFBGwvxXAVPAEKMVnmAABAgQIFBGwvxXAVPAEKMVnmAABAgQIFBGwvxXAVPAEKMVnmAABAgQIFBGwvxXAVPAEKMVnmAABAgQIFBGwvxXAVPAEKMVnmAABAgQIFBGwvxXAVPAEKMVnmAABAgQIFBGwvxXAVPAEKMVnmAABAgQIFBGwvxXAVPAEKMVnmAABAgQIFBGwvxXAVPAEKMVnmAABAgQIFBGwvxXAVPAEKMVnmAABAgQIFBGwvxXAVPAEKMVnmAABAgQIFBGwvxXAVPAEKMVnmAABAgQIFBGwvxXAVPAEKMVnmAABAgQIFBGwvxXAVPAEKMVnmAABAgQIFBGwvxXAVPAEKMVnmAABAgQIFBGwvxtcAN9///2YM2dO/PznP4/X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HJSo5QNYtkw16IEsByVq6QCOLTG1dBDLhhfAga+Bufrqq+sfAy9ZsiSuueaa+MMf/lD/aHewmwANJtT6/2fZutUnHcmxPY6uELTPkWX7LL2+WbZPoOEFsIKsrv5ddtll9RdBT5o0Ka644oo4/PDDWzKuPhFcfV3M7Nmz4zOf+UxLMw7atADL9iSDY3scq3thybJ9Au25J5lsj6PX9787NvpHwO2LknsiQIAAAQIECHSPgALYPefKIyVAgAABAgQItEVAAWwLozshQIAAAQIECHSPgALYPefKIyVAgAABAgQItEVAAWwLozshQIAAAQIECHSPgAI4zHNVfXp44cKF9aeHJ06cGIsWLYrDDjtsmPfW3LH777+/dnziiSdqy2XLlsWxxx7bXJBhPvPq0+i33npr/Rtsttxyy/rXGy5YsCD23HPPYd5jc8euuuqqqP7785//XCNUr++LL744vv71rzcXpQ3PvMrohRdeGNXvW6/+vnRrXWBTv4Z0++23j9dff731O3HkeoFXXnklZs2aFXfddVe88847MWHChLjuuuvq7wVu0k0BHMbZHvj+wKoEHnroobF48eK49tpr4+mnn45ddtllGPfY3JHqBVj9PubJkyfH8ccfrwAOMwpHH310nHTSSXHQQQfF+++/HxdddFE89dRTdSa33nrrYd5rM8d+/etfx6hRo+ILX/hCDVD9bvDqHylPPvlkXQbdhi7w2GOPxYknnhg9PT0xZcoUBXCIhFUB/OUvfxn33nvv+skqo5///OeHeE8Or3712/7771/ncPr06TF27Niofh/wbrvtFuPHj28UkAI4jNNd/QaRqrBUVwkGbnvvvXd95ar6V67b8ARGjBihAA6P7iNTb775Zv0X2/Lly1v+Xss2/dGb5d1su+22dQn83ve+t1k+v//IJ/X222/Xf19W/2CeO3du7LfffgrgEMGrAnjbbbfFypUrhzjp8A8LXHDBBfVFhwceeKDxOArgECPQjt8hPMQ/sjGHK4DtO9XPP/987LHHHvVVwOoLzt2GJ/DBBx/ELbfcElOnTq2vAFa/KtJtaAKVXVWgqy/ZP+KIIxTAofHVR1cFsPoHyJgxY+pfOlBdhLjkkkti9913H8a9NXukeg0fddRR8fLLL9f/QN5pp53izDPPjGnTpjUORgEc4il/9dVX68BU/4Ko3mc1cKtejNWPip599tkh3qPDBwQUwPZkob+/v/591tWPOvwrd3imVXGufj3ku+++G5/97Gfjpptuim984xvDu7MGT9188831Vb/HH388Ro8erQAOMwvVW2X++c9/1u9V+8tf/lKbVu/3rX5t6XbbbTfMe23mWJXD6nbeeefFCSecEI8++mjMnDmzfivXqaee2igUBXCIp3ugAK5YsaJeEAO3efPmxY033li/KN2GJ6AADs/tw1NnnXVW3HnnnfHggw/Gzjvv3J47bdi9VFf6X3rppXjrrbfiV7/6Vf0e3+pqgSuArQdh1apVceCBB8Y999wT++67bz3oCmDrfp905D/+8Y/6/Wrnn39+XWTcWhfYYost6lxWO3zgds4550T1PtWHH3649TvaDI5UAId4Ev0IeIhgQzhcARwC1sccevbZZ9fvFao+XT1u3Lj8HbqHWuCrX/1qvXCrqwRurQlUOTzuuOPqD9QM3KofqVev85EjR9a/a3nD/9favTpqQODII4+sP6i04XvR6QwusOuuu0ZlV/2jbuBWGVZXVatPBzfppgAO42xX77+oPi5eval54FZdGah+7OZDIMMA/f8jCuDw7aof+1blr/oanfvuu69+/59b+wS+8pWvRG9vb1x//fXtu9PN/J7Wrl0bL7744kbP8vTTT4+99tqr/goO700dfgCq8lz9g+SMM86ov6LIrXWBk08+Oaqr0xu+Pebcc8+NRx55ZKOrgq3fY/ceqQAO49wNfA3M1VdfXf8YeMmSJXHNNdfU78eo/nXh1rpA9QnB6gML1a36aP7ll19efzy/etO4r9Rp3bF6E3P1PrXbb799o+/+q940Xn0voFvrAtV31VXf+VcVvqrEVO9ju/TSS+Puu++urxy4DV/Aj4CHZ/eDH/wgvvWtb9V/J77xxhv11arqLQnVe1XtnKGZVj/qrd6/39fXV381UfUewOoDINUeP+WUU4Z2Z11+tAI4zBNYXf277LLL6i8vrv4lW33C7fDDDx/mvTV3rLpaVRW+D9+qTw662tJ6Lqqrp5u6LV26NE477bTW78iR9Ve9/Pa3v61f21WB/uIXv1hfsVL+8uFQAIdnWH3HZ/W2jr/+9a/1d/996Utfip/85Cfekzo8zrjjjjti9uzZ8dxzz9VvlaneR+lTwMPENEaAAAECBAgQINA9Aq4Ads+58kgJECBAgAABAm0RUADbwuhOCBAgQIAAAQLdI6AAds+58kgJECBAgAABAm0RUADbwuhOCBAgQIAAAQLdI6AAds+58kgJECBAgAABAm0RUADbwuhOCBAgQIAAAQLdI6AAds+58kgJECBAgAABAm0RUADbwuhOCBAgQIAAAQLdI6AAds+58kgJECBAgAABAm0RUADbwuhOCBAgQIAAAQLdI6AAds+58kgJECBAgAABAm0RUADbwuhOCBAgQIAAAQLdI6AAds+58kgJECBAgAABAm0RUADbwuhOCBAgQIAAAQLdI6AAds+58kgJECBAgAABAm0RUADbwuhOCBAgQIAAAQLdI6AAds+58kgJECBAgAABAm0RUADbwuhOCBAgQIAAAQLdI6AAds+58kgJECBAgAABAm0RUADbwuhOCBAgQIAAAQLdI6AAds+58kgJECBAgAABAm0RUADbwuhOCBAgQIAAAQLdI6AAds+58kgJECBAgAABAm0RUADbwuhOCBAgQIAAAQLdI6AAds+58kgJECBAgAABAm0RUADbwuhOCBAgQIAAAQLdI6AAds+58kgJECBAgAABAm0RUADbwuhOCBAgQIAAAQLdI6AAds+58kgJECBAgAABAm0RUADbwuhOCBAgQIAAAQLdI6AAds+58kgJECBAgAABAm0R+H8u39Ejp1kVNAAAAABJRU5ErkJggg==\" width=\"640\">"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "(0.0, 6.0, 0.0, 10.0)"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# create a new figure\n",
    "plt.figure()\n",
    "\n",
    "# plot the point (3,2) using the circle marker\n",
    "plt.plot(3, 2, 'o')\n",
    "\n",
    "# get the current axes\n",
    "ax = plt.gca()\n",
    "\n",
    "# Set axis properties [xmin, xmax, ymin, ymax]\n",
    "ax.axis([0,6,0,10])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "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_dpi_ratio', { dpi_ratio: fig.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 = 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(\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",
       "    );\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('style', 'box-sizing: content-box;');\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; position: absolute; left: 0; top: 0; 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",
       "            canvas.setAttribute(\n",
       "                'style',\n",
       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
       "            );\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",
       "        return function (event) {\n",
       "            return fig.mouse_event(event, name);\n",
       "        };\n",
       "    }\n",
       "\n",
       "    rubberband_canvas.addEventListener(\n",
       "        'mousedown',\n",
       "        on_mouse_event_closure('button_press')\n",
       "    );\n",
       "    rubberband_canvas.addEventListener(\n",
       "        'mouseup',\n",
       "        on_mouse_event_closure('button_release')\n",
       "    );\n",
       "    // Throttle sequential mouse events to 1 every 20ms.\n",
       "    rubberband_canvas.addEventListener(\n",
       "        'mousemove',\n",
       "        on_mouse_event_closure('motion_notify')\n",
       "    );\n",
       "\n",
       "    rubberband_canvas.addEventListener(\n",
       "        'mouseenter',\n",
       "        on_mouse_event_closure('figure_enter')\n",
       "    );\n",
       "    rubberband_canvas.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",
       "    this.rubberband_canvas.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",
       "    var cursor = msg['cursor'];\n",
       "    switch (cursor) {\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.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",
       "            /* 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",
       "\n",
       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
       "                evt.data\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",
       "// 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",
       "    }\n",
       "    if (e.target) {\n",
       "        targ = e.target;\n",
       "    } else if (e.srcElement) {\n",
       "        targ = e.srcElement;\n",
       "    }\n",
       "    if (targ.nodeType === 3) {\n",
       "        // defeat Safari bug\n",
       "        targ = targ.parentNode;\n",
       "    }\n",
       "\n",
       "    // pageX,Y are the mouse positions relative to the document\n",
       "    var boundingRect = targ.getBoundingClientRect();\n",
       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\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",
       "        }\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",
       "        this.canvas.focus();\n",
       "        this.canvas_div.focus();\n",
       "    }\n",
       "\n",
       "    var x = canvas_pos.x * this.ratio;\n",
       "    var y = canvas_pos.y * this.ratio;\n",
       "\n",
       "    this.send_message(name, {\n",
       "        x: x,\n",
       "        y: y,\n",
       "        button: event.button,\n",
       "        step: event.step,\n",
       "        guiEvent: simpleKeys(event),\n",
       "    });\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",
       "    // Prevent repeat events\n",
       "    if (name === 'key_press') {\n",
       "        if (event.which === this._key) {\n",
       "            return;\n",
       "        } else {\n",
       "            this._key = event.which;\n",
       "        }\n",
       "    }\n",
       "    if (name === 'key_release') {\n",
       "        this._key = null;\n",
       "    }\n",
       "\n",
       "    var value = '';\n",
       "    if (event.ctrlKey && event.which !== 17) {\n",
       "        value += 'ctrl+';\n",
       "    }\n",
       "    if (event.altKey && event.which !== 18) {\n",
       "        value += 'alt+';\n",
       "    }\n",
       "    if (event.shiftKey && event.which !== 16) {\n",
       "        value += 'shift+';\n",
       "    }\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, 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 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\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis, CTRL fixes aspect\", \"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\";/* 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.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 = 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(\"<div id='\" + id + \"'></div>\");\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",
       "        '<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 / this.ratio;\n",
       "    var dataURL = this.canvas.toDataURL();\n",
       "    this.cell_info[1]['text/html'] =\n",
       "        '<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 () {\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 = '<i class=\"fa ' + image + ' fa-lg\"></i>';\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 = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\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",
       "    var manager = IPython.notebook.keyboard_manager;\n",
       "    if (!manager) {\n",
       "        manager = IPython.keyboard_manager;\n",
       "    }\n",
       "\n",
       "    // Check for shift+enter\n",
       "    if (event.shiftKey && event.which === 13) {\n",
       "        this.canvas_div.blur();\n",
       "        // select the cell after this one\n",
       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
       "        IPython.notebook.select(index + 1);\n",
       "    }\n",
       "};\n",
       "\n",
       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
       "    fig.ondownload(fig, null);\n",
       "};\n",
       "\n",
       "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": [
       "<IPython.core.display.Javascript object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAgAElEQVR4Xu3dDazV9Zkn8OdizZRBgWqGUQSn7IpGyyYDKROX+lKNqXS6ihFj2WSr+JYqlqyaVIeSuNCaKNXYtU1qU+PLUqvr6oDoOrrNxCAvus7ECQ1bJBWViQVUuqtUayRB7uZ3Zi+LcOEe73Pv/d17/p+TGKOc597z//y/l+fL/7zQ1d3d3R1uBAgQIECAAAECjRHoUgAbc64dKAECBAgQIECgJaAACgIBAgQIECBAoGECCmDDTrjDJUCAAAECBAgogDJAgAABAgQIEGiYgALYsBPucAkQIECAAAECCqAMECBAgAABAgQaJqAANuyEO1wCBAgQIECAgAIoAwQIECBAgACBhgkogA074Q6XAAECBAgQIKAAygABAgQIECBAoGECCmDDTrjDJUCAAAECBAgogDJAgAABAgQIEGiYgALYsBPucAkQIECAAAECCqAMECBAgAABAgQaJqAANuyEO1wCBAgQIECAgAIoAwQIECBAgACBhgkogA074Q6XAAECBAgQIKAAygABAgQIECBAoGECCmDDTrjDJUCAAAECBAgogDJAgAABAgQIEGiYgALYsBPucAkQIECAAAECCqAMECBAgAABAgQaJqAANuyEO1wCBAgQIECAgAIoAwQIECBAgACBhgkogA074Q6XAAECBAgQIKAAygABAgQIECBAoGECCmDDTrjDJUCAAAECBAgogDJAgAABAgQIEGiYgALYsBPucAkQIECAAAECCqAMECBAgAABAgQaJqAANuyEO1wCBAgQIECAgAIoAwQIECBAgACBhgkogA074Q6XAAECBAgQIKAAygABAgQIECBAoGECCmDDTrjDJUCAAAECBAgogDJAgAABAgQIEGiYgALYsBPucAkQIECAAAECCqAMECBAgAABAgQaJqAANuyEO1wCBAgQIECAgAIoAwQIECBAgACBhgkogA074Q6XAAECBAgQIKAAygABAgQIECBAoGECCmDDTrjDJUCAAAECBAgogDJAgAABAgQIEGiYgALYsBPucAkQIECAAAECCqAMECBAgAABAgQaJqAANuyEO1wCBAgQIECAgAIoAwQIECBAgACBhgkogA074Q6XAAECBAgQIKAAygABAgQIECBAoGECCmDDTrjDJUCAAAECBAgogDJA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3x1SALu6unoNS3mX7/z581u/Vv69devW1hXC3m4K4KD/vPkGBAgQIEBgWAgogB1SAGulSYBqyfu+BAgQIECg/wL2twLY//R4DWDKzjABAgQIEKgloAAqgKnsCVCKzzABAgQIEKgiYH8rgKngCVCKzzABAgQIEKgiYH8rgKngCVCKzzABAgQIEKgiYH8rgKngCVCKzzABAgQIEKgiYH8rgKngCVCKzzABAgQIEKgiYH8rgKngCVCKzzABAgQIEKgiYH8rgKngCVCKzzABAgQIEKgiYH8rgKngCVCKzzABAgQIEKgiYH8rgKngCVCKzzABAgQIEKgiYH8rgKngCVCKzzABAgQIEKgiYH8rgKngCVCKzzABAgQIEKgiYH8rgKngCVCKzzABAgQIEKgiYH8rgKngCVCKzzABAgQIEKgiYH8rgKngCVCKzzABAgQIEKgiYH8rgKngCVCKzzABAgQIEKgiYH8rgKngCVCKzzABAgQIEKgiYH8rgKngCVCKzzABAgQIEKgiYH8rgKngCVCKzzABAgQIEKgiYH8rgKngCVCKzzABAgQIEKgiYH8rgKngCVCKzzABAgQIEKgiYH8rgKngCVCKzzABAgQIEKgiYH8rgKngCVCKzzABAgQIEKgiYH8rgKngCVCKzzABAgQIEKgiYH8rgKngCVCKzzABAgQIEKgiYH8rgKngCVCKzzABAgQIEKgiYH8rgKngCVCKzzABAgQIEKgiYH8rgKngCVCKzzABAgQIEKgiYH8rgKngCVCKzzABAgQIEKgiYH8rgKngCVCKzzABAgQIEKgiYH8rgKngCVCKzzABAgQIEKgiYH8rgKngCVCKzzABAgQIEKgiYH8rgKngCVCKzzABAgQIEKgiYH8rgKngCVCKzzABAgQIEKgiYH8rgKngCVCKzzABAgQIEKgiYH8rgKngCVCKzzABAgQIEKgiYH8rgKngCVCKzzABAgQIEKgiYH8rgKngCVCKzzABAgQIEKgiYH8rgKngCVCKzzABAgQIEKgiYH8rgKngCVCKzzABAgQIEKgiYH8rgKngCVCKzzABAgQIEKgiYH8rgKngCVCKzzABAgQIEKgiYH8rgKngCVCKzzABAgQIEKgiYH8rgKngCVCKzzABAgQIEKgiYH8rgKngCVCKzzABAgQIEKgiYH8rgKngCVCKzzABAgQIEKgiYH8rgKngCVCKzzABAgQIEKgiYH8rgKngCVCKzzABAgQIEKgiYH8rgKngCVCKzzABAgQIEKgiYH8rgKngCVCKzzABAgQIEKgiYH8rgKngCVCKzzABAgQIEKgiYH8rgKngCVCKzzABAgQIEKgiYH8rgKngCVCKzzABAgQIEKgiYH8rgKngCVCKzzABAgQIEKgiYH8rgKngCVCKzzABAgQIEKgiYH8rgKngCVCKzzABAgQIEKgiYH8rgKngCVCKzzABAgQIEKgiYH93SAG8/fbbY8WKFbF58+YYPXp0zJo1K5YtWxannHLKIYNV7n/vvffGhg0bYvfu3fGlL30plixZEueff37bYRSgtqnckQABAgQIDBsB+7tDCuDs2bNj3rx5MXPmzNizZ08sXrw4Nm7cGJs2bYoxY8b0GrgbbrghJk6cGOecc06MHz8+Hnzwwbjrrrvi5ZdfjunTp7cVUgFqi8mdCBAgQIDAsBKwvzukAB6Yqp07d8aECRPihRdeiLPOOqvt0JWrgN/85jfj1ltvbWtGgNpicicCBAgQIDCsBOzvDi2AW7ZsialTp7auAk6bNq2t0O3duze++MUvxs033xzf+c53ep0pTxWXf3puJUCTJ0+OXbt2xdixY9v6Pu5EgAABAgQI1BVQADuwAHZ3d8ecOXPivffei7Vr17adsDvvvDPuuOOOePXVV1tXD3u7ldcILl269KBfUgDbZnZHAgQIECBQXUAB7MACeP3118czzzwT69ati0mTJrUVskcffTSuvvrqWLVqVZx33nmHnHEFsC1OdyJAgAABAsNaQAHssAK4cOHCePLJJ2PNmjUxZcqUtsL32GOPxRVXXBGPP/54fOMb32hrpudOAvSZuNyZAAECBAgMCwH7u0MKYHnat5S/lStXxurVq1uv/2vnVq78XXnllVH+fdFFF7Uz8qn7CNBnJjNAgAABAgSqC9jfHVIAFyxYEI888kjrKdz9P/tv3Lhxrc8FLLdFixbFtm3bYvny5a3/LqXvsssui3vuuScuvvjifWEs9y9z7dwEqB0l9yFAgAABAsNLwP7ukALY1dXVa7LKZ/vNnz+/9Wvl31u3bm1dISy3r371q62PiTnwdvnll8dDDz3UVlIFqC0mdyJAgAABAsNKwP7ukAJYK1UCVEve9yVAgAABAv0XsL8VwP6nJyIEKMVnmAABAgQIVBGwvxXAVPAEKMVnmAABAgQIVBGwvxXAVPAEKMVnmAABAgQIVBGwvxXAVPAEKMVnmAABAgQIVBGwvxXAVPAEKMVnmAABAgQIVBGwvxXAVPAEKMVnmAABAgQIVBGwvxXAVPAEKMVnmAABAgQIVBGwvxXAVPAEKMVnmAABAgQIVBGwvxXAVPAEKMVnmAABAgQIVBGwvxXAVPAEKMVnmAABAgQIVBGwvxXAVPAEKMVnmAABAgQIVBGwvxXAVPAEKMVnmAABAgQIVBGwvxXAVPAEKMVnmAABAgQIVBGwvxXAVPAEKMVnmAABAgQIVBGwvxXAVPAEKMVnmAABAgQIVBGwvxXAVPAEKMVnmAABAgQIVBGwvxXAVPAEKMVnmAABAgQIVBGwvxXAVPAEKMVnmAABAgQIVBGwvxXAVPAEKMVnmAABAgQIVBGwvxXAVPAEKMVnmAABAgQIVBGwvxXAVPAEKMVnmAABAgQIVBGwvxXAVPAEKMVnmAABAgQIVBGwvxXAVPAEKMVnmAABAgQIVBGwvxXAVPAEKMVnmAABAgQIVBGwvxXAVPAEKMVnmAABAgQIVBGwvxXAVPAEKMVnmAABAgQIVBGwvxXAVPAEKMVnmAABAgQIVBGwvxXAVPAEKMVnmAABAgQIVBGwvxXAVPAEKMVnmAABAgQIVBGwvxXAVPAEKMVnmAABAgQIVBGwvxXAVPAEKMVnmAABAgQIVBGwvxXAVPAEKMVnmAABAgQIVBGwvxXAVPAEKMVnmAABAgQIVBGwvxXAVPAEKMVnmAABAgQIVBGwvxXAVPAEKMVnmAABAgQIVBGwvxXAVPAEKMVnmAABAgQIVBGwvxXAVPAEKMVnmAABAgQIVBGwvxXAVPAEKMVnmAABAgQIVBGwvxXAVPAEKMVnmAABAgQIVBGwvxXAVPAEKMVnmAABAgQIVBGwvxXAVPAEKMVnmAABAgQIVBGwvxXAVPAEKMVnmAABAgQIVBGwvxXAVPAEKMVnmAABAgQIVBGwvxXAVPAEKMVnmAABAgQIVBGwvxXAVPAEKMVnmAABAgQIVBGwvxXAVPAEKMVnmAABAgQIVBGwvxXAVPAEKMVnmAABAgQIVBGwvxXAVPAEKMVnmAABAgQIVBGwvxXAVPAEKMVnmAABAgQIVBGwvxXAVPAEKMVnmAABAgQIVBGwvxXAVPAEKMVnmAABAgQIVBGwvxXAVPAE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JkCAAAECVQTsbwUwFTwBSvEZJkCAAAECVQTsbwUwFTwBSvEZJkCAAAECVQTsbwUwFTwBSvEZJkCAAAECVQTsbwUwFTwBSvEZJkCAAAECVQTsbwUwFTwBSvEZJkCAAAECVQTsbwUwFTwBSvEZJkCAAAECVQTsbwUwFTwBSvEZJkCAAAECVQTiPUsAABPISURBVATsbwUwFTwBSvEZJkCAAAECVQTsbwUwFTwBSvEZJkCAAAECVQTsbwUwFTwBSvEZJkCAAAECVQTsbwUwFTwBSvEZJkCAAAECVQTsbwUwFTwBSvEZJkCAAAECVQTsbwUwFTwBSvEZJkCAAAECVQTsbwUwFTwBSvEZJkCAAAECVQTsbwUwFTwBSvEZJkCAAAECVQTsbwUwFTwBSvEZJkCAAAECVQTsbwUwFTwBSvEZJkCAAAECVQTsbwUwFTwBSvEZJkCAAAECVQTsbwUwFTwBSvEZJkCAAAECVQTsbwUwFTwBSvEZJkCAAAECVQTsbwUwFTwBSvEZJkCAAAECVQTsbwUwFTwBSvEZJkCAAAECVQTsbwUwFTwBSvEZJkCAAAECVQTsbwUwFTwBSvEZJkCAAAECVQTsbwUwFTwBSvEZJkCAAAECVQTsbwUwFTwBSvEZJkCAAAECVQTsbwUwFTwBSvEZJkCAAAECVQTsbwUwFTwBSvEZJkCAAAECVQTsbwUwFTwBSvEZJkCAAAECVQTsbwUwFTwBSvEZJkCAAAECVQTsbwUwFTwBSvEZJkCAAAECVQTsbwUwFTwBSvEZJkCAAAECVQTsbwUwFTwBSvEZJkCAAAECVQTsbwUwFTwBSvEZJkCAAAECVQTsbwUwFTwBSvEZJkCAAAECVQTsbwUwFTwBSvEZJkCAAAECVQTsbwUwFTwBSvEZJkCAAAECVQTsbwUwFTwBSvEZJkCAAAECVQTsbwUwFTwBSvEZJkCAAAECVQTsbwUwFTwBSvEZJkCAAAECVQTsbwUwFTwBSvEZJkCAAAECVQTsbwUwFTwBSvEZJkCAAAECVQTsbwUwFTwBSvEZJkCAAAECVQTsbwUwFTwBSvEZJkCAAAECVQTsbwUwFTwBSvEZJkCAAAECVQTsbwUwFTwBSvEZJkCAAAECVQTsbwUwFTwBSvEZJkCAAAECVQTsbwUwFTwBSvEZJkCAAAECVQTsbwUwFTwBSvEZJkCAAAEC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1lsbLtje4X8W5/L7dPkD4xFHHBFPPvmkAtgecUfcSwHsiNM4tAfRTjEpV0Z++9vfxpe//OX4xS9+0bqqcuGFF8YPfvCD1lNubn0LtOP84osvtq6UlEL+9a9/vXWV9dJLL41TTz01fvazn/X9TdyjJbBly5bWEixXActVvt5upRiWK1D33HPPvl8u7sX7o48+iiOPPJJmHwLtOB/4Jfbu3Rtf/OIXW0+3f+c732HchkC7zuXq6k9/+tPWH2DKMzUKYBu4HXQXBbCDTuZQHUo7xaQ8JbF69eo477zzWn9q//3vf996uuzcc8+NBx54YKge6oj+Pu04lwN84okn4oorroiPP/649XRmKdrl/ykk7Z3+7u7uKC9XeO+992Lt2rWHHDr55JNj/vz58b3vfW/ffUoB/8pXvhLbt2+P448/vr1v2NB7tet8IE957fEdd9zRuvJartK6HV6gXefymuEzzjijlfmS7fI6SwWwWelSAJt1vgfkaNspJl/72tdav7GUN3+UNyaUW3lx9yWXXBJ//OMfXQVs40y041xes1ZK9o033th6kXx5g853v/vd1mvb7r///ja+i7tcf/318cwzz0R5PWV5o9KhbmVJlqJd/qrDnlt5HWBZosX9uOOOg3kYgXad9/8S5fWVV199daxataqVc7e+Bdpx/uSTT+L000+Pq666at+bmBTAvm077R4KYKed0SE4nnaKyeWXX956kXx5KqLnVv4Ef9ppp7WeGi5Pt7kdXqAd529961utK3+PP/74vi9WisyZZ57pqlQbAVu4cGHrqkd59/WUKVMOO+Ep4DZAD3GXz+Lc8yUee+yxVuEu2f7GN77R/2/eoMl2nd9///34whe+0HrdX8+tPNVerh6W//erX/2q9WyNW2cLKICdfX4H5ejaKSY///nPo7ybr7wm7aijjmo9jvKn+Isvvjg+/PBDVwDbODPtOJd3n37uc5+Lsix7buX1POWd1uUdweXdlG4HC5RFV5ZleQ1fealCO38gKW8Cefrpp1vvFO65XXfdda0XzXsTSO8p649z+Urlyl/5uKjy774+bkq+o1XcPkueS9nbP8fFsLwW8Pnnn2+9fKT8YehQ74bn3TkCCmDnnMtBPZJS2nqu5pUXwt99992tNx+Ud/ieeOKJrafFSuFYvnx563GU+5c3IpSnGZYuXdp6DWB5Kqd8ZMl99903qI91JH/xz+r80EMPtT6W5Mc//vG+p4BL8R41alTrYzPcehcor0d95JFHWn8o2f+z/8rLFXrepHRgpns+BqZ8BEwxL6WvvAvYx8AcOmX9cS6el112WevNNuUPjD23cl56Xk4i158W6I/zgYaeAm5eqhTA5p3zfh1xuUpSCt+Bt/JUbykh5cXxW7dubV1N6bmVD9ktfyotTwWXDyUu75Ys7zTzLuBDn4L+OJePfSnv+C0FpXxuWnnqpnyo8QknnNCvc92EoXJ1tbdbeVdkyXK59Zbp8jEx5fWWPR8EXa4K+iDoQyemP85f/epXWx/Hc6jfa5qQz896jP1xVgA/q3Ln3V8B7Lxz6ogIECBAgAABAocVUAAFhAABAgQIECDQMAEFsGEn3OESIECAAAECBBRAGSBAgAABAgQINExAAWzYCXe4BAgQIECAAAEFUAYIECBAgAABAg0TUAAbdsIdLgECBAgQIEBAAZQBAgQIECBAgEDDBBTAhp1wh0uAAAECBAgQUABlgAABAgQIECDQMAEFsGEn3OESIECAAAECBBRAGSBAgAABAgQINExAAWzYCXe4BAgQIECAAAEFUAYIECBAgAABAg0TUAAbdsIdLgECBAgQIEBAAZQBAgQIECBAgEDDBBTAhp1wh0uAAAECBAgQUABlgAABAgQIECDQMAEFsGEn3OESIECAAAECBBRAGSBAgAABAgQINExAAWzYCXe4BAgQIECAAAEFUAYIECBAgAABAg0TUAAbdsIdLgECBAgQIEBAAZQBAgQIECBAgEDDBBTAhp1wh0uAAAECBAgQUABlgAABAgQIECDQMAEFsGEn3OESIECAAAECBBRAGSBAgAABAgQINExAAWzYCXe4BAgQIECAAAEFUAYIECBAgAABAg0TUAAbdsIdLgECBAgQIEBAAZQBAgQIECBAgEDDBP4vBwxeUJEDX0sAAAAASUVORK5CYII=\" width=\"640\">"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "[<matplotlib.lines.Line2D at 0x24b125eed00>]"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "%matplotlib notebook\n",
    "\n",
    "# create a new figure\n",
    "plt.figure()\n",
    "\n",
    "# plot the point (1.5, 1.5) using the circle marker\n",
    "plt.plot(1.5, 1.5, 'o')\n",
    "# plot the point (2, 2) using the circle marker\n",
    "plt.plot(2, 2, 'o')\n",
    "# plot the point (2.5, 2.5) using the circle marker\n",
    "plt.plot(2.5, 2.5, 'o')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<matplotlib.lines.Line2D at 0x24b125ee640>,\n",
       " <matplotlib.lines.Line2D at 0x24b125ee9a0>,\n",
       " <matplotlib.lines.Line2D at 0x24b125eed00>,\n",
       " <matplotlib.spines.Spine at 0x24b12351790>,\n",
       " <matplotlib.spines.Spine at 0x24b12351880>,\n",
       " <matplotlib.spines.Spine at 0x24b12351970>,\n",
       " <matplotlib.spines.Spine at 0x24b12351a60>,\n",
       " <matplotlib.axis.XAxis at 0x24b12351700>,\n",
       " <matplotlib.axis.YAxis at 0x24b12351e20>,\n",
       " Text(0.5, 1.0, ''),\n",
       " Text(0.0, 1.0, ''),\n",
       " Text(1.0, 1.0, ''),\n",
       " <matplotlib.patches.Rectangle at 0x24b12365460>]"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# get current axes\n",
    "ax = plt.gca()\n",
    "# get all the child objects the axes contains\n",
    "ax.get_children()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Scatterplots"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "scrolled": false
   },
   "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_dpi_ratio', { dpi_ratio: fig.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 = 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(\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",
       "    );\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('style', 'box-sizing: content-box;');\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; position: absolute; left: 0; top: 0; 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",
       "            canvas.setAttribute(\n",
       "                'style',\n",
       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
       "            );\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",
       "        return function (event) {\n",
       "            return fig.mouse_event(event, name);\n",
       "        };\n",
       "    }\n",
       "\n",
       "    rubberband_canvas.addEventListener(\n",
       "        'mousedown',\n",
       "        on_mouse_event_closure('button_press')\n",
       "    );\n",
       "    rubberband_canvas.addEventListener(\n",
       "        'mouseup',\n",
       "        on_mouse_event_closure('button_release')\n",
       "    );\n",
       "    // Throttle sequential mouse events to 1 every 20ms.\n",
       "    rubberband_canvas.addEventListener(\n",
       "        'mousemove',\n",
       "        on_mouse_event_closure('motion_notify')\n",
       "    );\n",
       "\n",
       "    rubberband_canvas.addEventListener(\n",
       "        'mouseenter',\n",
       "        on_mouse_event_closure('figure_enter')\n",
       "    );\n",
       "    rubberband_canvas.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",
       "    this.rubberband_canvas.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",
       "    var cursor = msg['cursor'];\n",
       "    switch (cursor) {\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.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",
       "            /* 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",
       "\n",
       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
       "                evt.data\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",
       "// 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",
       "    }\n",
       "    if (e.target) {\n",
       "        targ = e.target;\n",
       "    } else if (e.srcElement) {\n",
       "        targ = e.srcElement;\n",
       "    }\n",
       "    if (targ.nodeType === 3) {\n",
       "        // defeat Safari bug\n",
       "        targ = targ.parentNode;\n",
       "    }\n",
       "\n",
       "    // pageX,Y are the mouse positions relative to the document\n",
       "    var boundingRect = targ.getBoundingClientRect();\n",
       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\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",
       "        }\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",
       "        this.canvas.focus();\n",
       "        this.canvas_div.focus();\n",
       "    }\n",
       "\n",
       "    var x = canvas_pos.x * this.ratio;\n",
       "    var y = canvas_pos.y * this.ratio;\n",
       "\n",
       "    this.send_message(name, {\n",
       "        x: x,\n",
       "        y: y,\n",
       "        button: event.button,\n",
       "        step: event.step,\n",
       "        guiEvent: simpleKeys(event),\n",
       "    });\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",
       "    // Prevent repeat events\n",
       "    if (name === 'key_press') {\n",
       "        if (event.which === this._key) {\n",
       "            return;\n",
       "        } else {\n",
       "            this._key = event.which;\n",
       "        }\n",
       "    }\n",
       "    if (name === 'key_release') {\n",
       "        this._key = null;\n",
       "    }\n",
       "\n",
       "    var value = '';\n",
       "    if (event.ctrlKey && event.which !== 17) {\n",
       "        value += 'ctrl+';\n",
       "    }\n",
       "    if (event.altKey && event.which !== 18) {\n",
       "        value += 'alt+';\n",
       "    }\n",
       "    if (event.shiftKey && event.which !== 16) {\n",
       "        value += 'shift+';\n",
       "    }\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, 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 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\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis, CTRL fixes aspect\", \"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\";/* 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.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 = 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(\"<div id='\" + id + \"'></div>\");\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",
       "        '<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 / this.ratio;\n",
       "    var dataURL = this.canvas.toDataURL();\n",
       "    this.cell_info[1]['text/html'] =\n",
       "        '<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 () {\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 = '<i class=\"fa ' + image + ' fa-lg\"></i>';\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 = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\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",
       "    var manager = IPython.notebook.keyboard_manager;\n",
       "    if (!manager) {\n",
       "        manager = IPython.keyboard_manager;\n",
       "    }\n",
       "\n",
       "    // Check for shift+enter\n",
       "    if (event.shiftKey && event.which === 13) {\n",
       "        this.canvas_div.blur();\n",
       "        // select the cell after this one\n",
       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
       "        IPython.notebook.select(index + 1);\n",
       "    }\n",
       "};\n",
       "\n",
       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
       "    fig.ondownload(fig, null);\n",
       "};\n",
       "\n",
       "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": [
       "<IPython.core.display.Javascript object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAgAElEQVR4Xu3de2zddfkH8KebwXqhNVscbFBgDKcZi46JCIQYQCdoJNMQyYbEgQaSQXRI1MFUWOMUliVc/tA5gQARYfHCJcNACCLjIggIMyBBgSAM3BxyqUPtCFt/+R5/XXbv6Z7TfdZ9XychIdn3OT3ndd7t8+73XNrW19fXFy4ECBAgQIAAAQK1EWhTAGvzWLujBAgQIECAAIGGgAIoCAQIECBAgACBmgkogDV7wN1dAgQIECBAgIACKAMECBAgQIAAgZoJKIA1e8DdXQIECBAgQICAAigDBAgQIECAAIGaCSiANXvA3V0CBAgQIECAgAIoAwQIECBAgACBmgkogDV7wN1dAgQIECBAgIACKAMECBAgQIAAgZoJKIA1e8DdXQIECBAgQICAAigDBAgQIECAAIGaCSiANXvA3V0CBAgQIECAgAIoAwQIECBAgACBmgkogDV7wN1dAgQIECBAgIACKAMECBAgQIAAgZoJKIA1e8DdXQIECBAgQICAAigDBAgQIECAAIGaCSiANXvA3V0CBAgQIECAgAIoAwQIECBAgACBmgkogDV7wN1dAgQIECBAgIACKAMECBAgQIAAgZoJKIA1e8DdXQIECBAgQICAAigDBAgQIECAAIGaCSiANXvA3V0CBAgQIECAgAIoAwQIECBAgACBmgkogDV7wN1dAgQIECBAgIACKAMECBAgQIAAgZoJKIA1e8DdXQIECBAgQICAAigDBAgQIECAAIGaCSiANXvA3V0CBAgQIECAgAIoAwQIECBAgACBmgkogDV7wN1dAgQIECBAgIACKAMECBAgQIAAgZoJKIA1e8DdXQIECBAgQICAAigDBAgQIECAAIGaCSiANXvA3V0CBAgQIECAgAIoAwQIECBAgACBmgkogDV7wN1dAgQIECBAgIACKAMECBAgQIAAgZoJKIA1e8DdXQIECBAgQICAAigDBAgQIECAAIGaCSiANXvA3V0CBAgQIECAgAIoAwQIECBAgACBmgkogDV7wN1dAgQIECBAgIACKAMECBAgQIAAgZoJKIA1e8DdXQIECBAgQICAAigDBAgQIECAAIGaCSiANXvA3V0CBAgQIECAgAIoAwQIECBAgACBmgkogDV7wN1dAgQIECBAgIACKAMECBAg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+g198fDzr8Watb0xZu/2OGL8qBg5oo1XiwTs75oXwIMOOiheeOGFreJ09tlnx49+9KMBYyZAAxI5gAABAgQGKXDHk6uie9lTsaqnd+Pk2M72uOikSXHi5LGDvDaHb0vA/q55AXzllVdi/fr1G7Px5JNPxrRp0+J3v/tdHHvssQN+1wjQgEQOIECAAIFBCFTlb/b1j0XfFjP95/4WnzZVCRyE5/YOtb9rXgC3DMa5554bt912WzzzzDPR1jbwqXYBasF3oasgQIAAgYZA9bTvMQvv3uzM36Y01Vbat7M97p97vKeDk5mxvxXAjRF66623Yty4cXHeeefFvHnzthmtdevWRfVf/6UKUFdXV/T09ERHR0cyjsYJECBAoM4CDz73asy88qEBCW4888g4asLoAY9zwPYFFEAFcGM6fvGLX8Spp54aL774YqMIbusyf/786O7u3uqfFEA/ZggQIEAgK3DripdjztIVA17NFTOmxPQp+w14nAMUwB1loK2vr2/LlxrUMjMnnHBC7LXXXrFs2bLt3n9nAGsZDXeaAAECu0TAGcBdwtz4Is4AOgPYCEL1TuCDDz44brrpppg+fXrTCRSgpqkcSIAAAQIDCPS/BnB1T+9WbwKpRr0GsHURsr8VwEaaqqd2lyxZEitXrox3vOMdTSdMgJqmciABAgQINCHQ/y7g6tBNn57zLuAm8AZxiP2tAMaGDRti/PjxMXPmzLjkkksGER+nkAeF5WACBAgQaErA5wA2xZQ6SAFUAOPOO++M6vV/f/nLX2LixImDCpQADYrLwQQIECDQpIC/BNIk1E4eZn8rgDsZnf+NCVCKzzABAgQIECgiYH8rgKngCVCKzzABAgQIECgiYH8rgKngCVCKzzABAgQIECgiYH8rgKngCVCKzzABAgQIECgiYH8rgKngCVCKzzABAgQIECgiYH8rgKngCVCKzzABAgQIECgiYH8rgKngCVCKzzABAgQIECgiYH8rgKngCVCKzzABAgQIECgiYH8rgKngCVCKzzABAgQIECgiYH8rgKngCVCKzzABAgQIECgiYH8rgKngCVCKzzABAgQIECgiYH8rgKngCVCKzzABAgQIECgiYH8rgKngCVCKzzABAgQIECgiYH8rgKngCVCKzzABAgQIECgiYH8rgKngCVCKzzABAgQIECgiYH8rgKngCVCKzzABAgQIECgiYH8rgKngCVCKzzABAgQIECgiYH8rgKngCVCKzzABAgQIECgiYH8rgKngCVCKzzABAgQIECgiYH8rgKngCVCKzzABAgQIECgiYH8rgKngCVCKzzABAgQIECgiYH8rgKngCVCKzzABAgQIECgiYH8rgKngCVCKzzABAgQIECgiYH8rgKngCVCKzzABAgQIECgiYH8rgKngCVCKzzABAgQIECgiYH8rgKngCVCKzzABAgQIECgiYH8rgKngCVCKzzABAgQIECgiYH8rgKngCVCKzzABAgQIECgiYH8rgKngCVCKzzABAgQIECgiYH8rgKngCVCKzzABAgQIECgiYH8rgKngCVCKzzABAgQIECgiYH8rgKngCVCKzzABAgQIECgiYH8rgKngCVCKzzABAgQIECgiYH8rgKngCVCKzzABAgQIECgiYH8rgKngCVCKzzABAgQIECgiYH8rgKngCVCKzzABAgQIECgiYH8rgKngCVCKzzABAgQIECgiYH8rgKngCVCKzzABAgS2K7B+Q188/PxrsWZtb4zZuz2OGD8qRo5oI0agJQL2d80L4Msvvxxz586N22+/Pf773//GxIkT4+qrr46PfvSjTQVMgJpichABAgQGJXDHk6uie9lTsaqnd+Pc2M72uOikSXHi5LGDui4HE9iWgP1d4wL4+uuvx2GHHRbHHXdczJ49O8aMGRPPPfdcHHTQQTFhwoSmvmMEqCkmBxEgQKBpgar8zb7+sejbYqL/3N/i06YqgU1rOnB7AvZ3jQvg+eefHw888EDcd999O/0dIkA7TWeQAAECWwlUT/ses/Duzc78bXpQVQL37WyP++ce7+lg+UkJ2N81LoCTJk2KE044IV566aVYvnx57LfffnH22WfHmWeeud1QrVu3Lqr/+i9VgLq6uqKnpyc6OjpSYTRMgACBugs8+NyrMfPKhwZkuPHMI+OoCaMHPM4BBJwB3H4G2vr6+rY8016LxLS3tzfu53nnnRdf/OIX4+GHH45zzz03lixZEl/+8pe3aTB//vzo7u7e6t8UwFpExp0kQGCIBW5d8XLMWbpiwK9yxYwpMX3KfgMe5wACCqACuJXAXnvtFYcffnj8/ve/3/hvX//61+ORRx6JBx98cJtizgD6YUKAAIGhE3AGcOhsXfPmAp4CrvFTwAceeGBMmzYtrrrqqo2pWLx4cSxY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\" width=\"640\">"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "<matplotlib.collections.PathCollection at 0x24b128b88b0>"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "%matplotlib notebook\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "x = np.array([1,2,3,4,5,6,7,8])\n",
    "y = x\n",
    "\n",
    "plt.figure()\n",
    "plt.scatter(x, y) # similar to plt.plot(x, y, '.'), but the underlying child objects in the axes are not Line2D"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%matplotlib notebook\n",
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "\n",
    "x = np.array([1,2,3,4,5,6,7,8])\n",
    "y = x\n",
    "\n",
    "# create a list of colors for each point to have\n",
    "# ['green', 'green', 'green', 'green', 'green', 'green', 'green', 'red']\n",
    "colors = ['green']*(len(x)-1)\n",
    "colors.append('red')\n",
    "\n",
    "plt.figure()\n",
    "\n",
    "# plot the point with size 100 and chosen colors\n",
    "plt.scatter(x, y, s=100, c=colors)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# convert the two lists into a list of pairwise tuples\n",
    "zip_generator = zip([1,2,3,4,5], [6,7,8,9,10])\n",
    "\n",
    "print(zip_generator)\n",
    "\n",
    "print(list(zip_generator))\n",
    "# the above prints:\n",
    "# [(1, 6), (2, 7), (3, 8), (4, 9), (5, 10)]\n",
    "\n",
    "zip_generator = zip([1,2,3,4,5], [6,7,8,9,10])\n",
    "# The single star * unpacks a collection into positional arguments\n",
    "print(*zip_generator)\n",
    "# the above prints:\n",
    "# (1, 6) (2, 7) (3, 8) (4, 9) (5, 10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# use zip to convert 5 tuples with 2 elements each to 2 tuples with 5 elements each\n",
    "print(list(zip((1, 6), (2, 7), (3, 8), (4, 9), (5, 10))))\n",
    "# the above prints:\n",
    "# [(1, 2, 3, 4, 5), (6, 7, 8, 9, 10)]\n",
    "\n",
    "\n",
    "zip_generator = zip([1,2,3,4,5], [6,7,8,9,10])\n",
    "# let's turn the data back into 2 lists\n",
    "x, y = zip(*zip_generator) # This is like calling zip((1, 6), (2, 7), (3, 8), (4, 9), (5, 10))\n",
    "print(x)\n",
    "print(y)\n",
    "# the above prints:\n",
    "# (1, 2, 3, 4, 5)\n",
    "# (6, 7, 8, 9, 10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%matplotlib notebook\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "plt.figure()\n",
    "# plot a data series 'Tall students' in red using the first two elements of x and y\n",
    "plt.scatter(x[:2], y[:2], s=100, c='red', label='Tall students')\n",
    "# plot a second data series 'Short students' in blue using the last three elements of x and y \n",
    "plt.scatter(x[2:], y[2:], s=100, c='blue', label='Short students')\n",
    "\n",
    "# add a label to the x axis\n",
    "plt.xlabel('The number of times the child kicked a ball')\n",
    "# add a label to the y axis\n",
    "plt.ylabel('The grade of the student')\n",
    "# add a title\n",
    "plt.title('Relationship between ball kicking and grades')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# import the artist class from matplotlib\n",
    "from matplotlib.artist import Artist\n",
    "\n",
    "def rec_gc(art, depth=0):\n",
    "    if isinstance(art, Artist):\n",
    "        # increase the depth for pretty printing\n",
    "        print(\"  \" * depth + str(art))\n",
    "        for child in art.get_children():\n",
    "            rec_gc(child, depth+2)\n",
    "\n",
    "# Call this function on the legend artist to see what the legend is made up of\n",
    "rec_gc(plt.legend())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Line Plots"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%matplotlib notebook\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "import numpy as np\n",
    "\n",
    "linear_data = np.array([1,2,3,4,5,6,7,8])\n",
    "exponential_data = linear_data**2\n",
    "\n",
    "plt.figure()\n",
    "# plot the linear data and the exponential data\n",
    "plt.plot(linear_data, '-o', exponential_data, '-o')\n",
    "\n",
    "# plot another series with a dashed red line\n",
    "plt.plot([22,44,55], '--r')\n",
    "\n",
    "plt.xlabel('Some data')\n",
    "plt.ylabel('Some other data')\n",
    "plt.title('A title')\n",
    "# add a legend with legend entries (because we didn't have labels when we plotted the data series)\n",
    "plt.legend(['Baseline', 'Competition', 'Us'])\n",
    "\n",
    "# fill the area between the linear data and exponential data\n",
    "plt.gca().fill_between(range(len(linear_data)), \n",
    "                       linear_data, exponential_data, \n",
    "                       facecolor='blue', \n",
    "                       alpha=0.25)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's try working with dates!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "plt.figure()\n",
    "\n",
    "observation_dates = np.arange('2017-01-01', '2017-01-09', dtype='datetime64[D]')\n",
    "\n",
    "plt.plot(observation_dates, linear_data, '-o',  observation_dates, exponential_data, '-o')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's try using pandas"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "\n",
    "plt.figure()\n",
    "observation_dates = np.arange('2017-01-01', '2017-01-09', dtype='datetime64[D]')\n",
    "observation_dates = map(pd.to_datetime, observation_dates) # trying to plot a map will result in an error\n",
    "plt.plot(observation_dates, linear_data, '-o',  observation_dates, exponential_data, '-o')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "plt.figure()\n",
    "observation_dates = np.arange('2017-01-01', '2017-01-09', dtype='datetime64[D]')\n",
    "observation_dates = list(map(pd.to_datetime, observation_dates)) # convert the map to a list to get rid of the error\n",
    "plt.plot(observation_dates, linear_data, '-o',  observation_dates, exponential_data, '-o')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = plt.gca().xaxis\n",
    "\n",
    "# rotate the tick labels for the x axis\n",
    "for item in x.get_ticklabels():\n",
    "    item.set_rotation(45)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# adjust the subplot so the text doesn't run off the image\n",
    "plt.subplots_adjust(bottom=0.25)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'plt' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-2-8272f75b8448>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0max\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgca\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m      2\u001b[0m \u001b[0max\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mset_xlabel\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Date'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      3\u001b[0m \u001b[0max\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mset_ylabel\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Units'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      4\u001b[0m \u001b[0max\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mset_title\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Exponential vs. Linear performance'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mNameError\u001b[0m: name 'plt' is not defined"
     ]
    }
   ],
   "source": [
    "ax = plt.gca()\n",
    "ax.set_xlabel('Date')\n",
    "ax.set_ylabel('Units')\n",
    "ax.set_title('Exponential vs. Linear performance')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# you can add mathematical expressions in any text element\n",
    "ax.set_title(\"Exponential ($x^2$) vs. Linear ($x$) performance\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Bar Charts"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "plt.figure()\n",
    "xvals = range(len(linear_data))\n",
    "plt.bar(xvals, linear_data, width = 0.3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "new_xvals = []\n",
    "\n",
    "# plot another set of bars, adjusting the new xvals to make up for the first set of bars plotted\n",
    "for item in xvals:\n",
    "    new_xvals.append(item+0.3)\n",
    "\n",
    "plt.bar(new_xvals, exponential_data, width = 0.3 ,color='red')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "from random import randint\n",
    "linear_err = [randint(0,15) for x in range(len(linear_data))] \n",
    "\n",
    "# This will plot a new set of bars with errorbars using the list of random error values\n",
    "plt.bar(xvals, linear_data, width = 0.3, yerr=linear_err)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# stacked bar charts are also possible\n",
    "plt.figure()\n",
    "xvals = range(len(linear_data))\n",
    "plt.bar(xvals, linear_data, width = 0.3, color='b')\n",
    "plt.bar(xvals, exponential_data, width = 0.3, bottom=linear_data, color='r')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# or use barh for horizontal bar charts\n",
    "plt.figure()\n",
    "xvals = range(len(linear_data))\n",
    "plt.barh(xvals, linear_data, height = 0.3, color='b')\n",
    "plt.barh(xvals, exponential_data, height = 0.3, left=linear_data, color='r')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "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.8.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
