diff --git a/01-Introduction to Matplotlib.ipynb b/01-Introduction to Matplotlib.ipynb
index 566d27f..ca0ae83 100644
--- a/01-Introduction to Matplotlib.ipynb
+++ b/01-Introduction to Matplotlib.ipynb
@@ -30,7 +30,7 @@
},
{
"cell_type": "code",
- "execution_count": 1,
+ "execution_count": 2,
"id": "surgical-forty",
"metadata": {},
"outputs": [],
@@ -41,7 +41,7 @@
},
{
"cell_type": "code",
- "execution_count": 2,
+ "execution_count": 3,
"id": "fifty-consortium",
"metadata": {},
"outputs": [],
@@ -59,7 +59,7 @@
},
{
"cell_type": "code",
- "execution_count": 3,
+ "execution_count": 4,
"id": "centered-range",
"metadata": {},
"outputs": [],
@@ -69,961 +69,13 @@
},
{
"cell_type": "code",
- "execution_count": 4,
+ "execution_count": 6,
"id": "recent-defense",
"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(\"
\");\n",
- " if (!fig.cell_info) {\n",
- " console.error('Failed to find cell for figure', id, fig);\n",
- " return;\n",
- " }\n",
- " fig.cell_info[0].output_area.element.on(\n",
- " 'cleared',\n",
- " { fig: fig },\n",
- " fig._remove_fig_handler\n",
- " );\n",
- "};\n",
- "\n",
- "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
- " var width = fig.canvas.width / fig.ratio;\n",
- " fig.cell_info[0].output_area.element.off(\n",
- " 'cleared',\n",
- " fig._remove_fig_handler\n",
- " );\n",
- " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
- "\n",
- " // Update the output cell to use the data from the current canvas.\n",
- " fig.push_to_output();\n",
- " var dataURL = fig.canvas.toDataURL();\n",
- " // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
- " // the notebook keyboard shortcuts fail.\n",
- " IPython.keyboard_manager.enable();\n",
- " fig.parent_element.innerHTML =\n",
- " '
';\n",
- " fig.close_ws(fig, msg);\n",
- "};\n",
- "\n",
- "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
- " fig.send_message('closing', msg);\n",
- " // fig.ws.close()\n",
- "};\n",
- "\n",
- "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
- " // Turn the data on the canvas into data in the output cell.\n",
- " var width = this.canvas.width / this.ratio;\n",
- " var dataURL = this.canvas.toDataURL();\n",
- " this.cell_info[1]['text/html'] =\n",
- " '
';\n",
- "};\n",
- "\n",
- "mpl.figure.prototype.updated_canvas_event = function () {\n",
- " // Tell IPython that the notebook contents must change.\n",
- " IPython.notebook.set_dirty(true);\n",
- " this.send_message('ack', {});\n",
- " var fig = this;\n",
- " // Wait a second, then push the new image to the DOM so\n",
- " // that it is saved nicely (might be nice to debounce this).\n",
- " setTimeout(function () {\n",
- " fig.push_to_output();\n",
- " }, 1000);\n",
- "};\n",
- "\n",
- "mpl.figure.prototype._init_toolbar = function () {\n",
- " var fig = this;\n",
- "\n",
- " var toolbar = document.createElement('div');\n",
- " toolbar.classList = 'btn-toolbar';\n",
- " this.root.appendChild(toolbar);\n",
- "\n",
- " function on_click_closure(name) {\n",
- " return function (_event) {\n",
- " return fig.toolbar_button_onclick(name);\n",
- " };\n",
- " }\n",
- "\n",
- " function on_mouseover_closure(tooltip) {\n",
- " return function (event) {\n",
- " if (!event.currentTarget.disabled) {\n",
- " return fig.toolbar_button_onmouseover(tooltip);\n",
- " }\n",
- " };\n",
- " }\n",
- "\n",
- " fig.buttons = {};\n",
- " var buttonGroup = document.createElement('div');\n",
- " buttonGroup.classList = 'btn-group';\n",
- " var button;\n",
- " for (var toolbar_ind in mpl.toolbar_items) {\n",
- " var name = mpl.toolbar_items[toolbar_ind][0];\n",
- " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
- " var image = mpl.toolbar_items[toolbar_ind][2];\n",
- " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
- "\n",
- " if (!name) {\n",
- " /* Instead of a spacer, we start a new button group. */\n",
- " if (buttonGroup.hasChildNodes()) {\n",
- " toolbar.appendChild(buttonGroup);\n",
- " }\n",
- " buttonGroup = document.createElement('div');\n",
- " buttonGroup.classList = 'btn-group';\n",
- " continue;\n",
- " }\n",
- "\n",
- " button = fig.buttons[name] = document.createElement('button');\n",
- " button.classList = 'btn btn-default';\n",
- " button.href = '#';\n",
- " button.title = name;\n",
- " button.innerHTML = '';\n",
- " button.addEventListener('click', on_click_closure(method_name));\n",
- " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
- " buttonGroup.appendChild(button);\n",
- " }\n",
- "\n",
- " if (buttonGroup.hasChildNodes()) {\n",
- " toolbar.appendChild(buttonGroup);\n",
- " }\n",
- "\n",
- " // Add the status bar.\n",
- " var status_bar = document.createElement('span');\n",
- " status_bar.classList = 'mpl-message pull-right';\n",
- " toolbar.appendChild(status_bar);\n",
- " this.message = status_bar;\n",
- "\n",
- " // Add the close button to the window.\n",
- " var buttongrp = document.createElement('div');\n",
- " buttongrp.classList = 'btn-group inline pull-right';\n",
- " button = document.createElement('button');\n",
- " button.classList = 'btn btn-mini btn-primary';\n",
- " button.href = '#';\n",
- " button.title = 'Stop Interaction';\n",
- " button.innerHTML = '';\n",
- " button.addEventListener('click', function (_evt) {\n",
- " fig.handle_close(fig, {});\n",
- " });\n",
- " button.addEventListener(\n",
- " 'mouseover',\n",
- " on_mouseover_closure('Stop Interaction')\n",
- " );\n",
- " buttongrp.appendChild(button);\n",
- " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
- " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
- "};\n",
- "\n",
- "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
- " var fig = event.data.fig;\n",
- " if (event.target !== this) {\n",
- " // Ignore bubbled events from children.\n",
- " return;\n",
- " }\n",
- " fig.close_ws(fig, {});\n",
- "};\n",
- "\n",
- "mpl.figure.prototype._root_extra_style = function (el) {\n",
- " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
- "};\n",
- "\n",
- "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
- " // this is important to make the div 'focusable\n",
- " el.setAttribute('tabindex', 0);\n",
- " // reach out to IPython and tell the keyboard manager to turn it's self\n",
- " // off when our div gets focus\n",
- "\n",
- " // location in version 3\n",
- " if (IPython.notebook.keyboard_manager) {\n",
- " IPython.notebook.keyboard_manager.register_events(el);\n",
- " } else {\n",
- " // location in version 2\n",
- " IPython.keyboard_manager.register_events(el);\n",
- " }\n",
- "};\n",
- "\n",
- "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
- " 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"
- ],
+ "application/javascript": "/* Put everything inside the global mpl namespace */\n/* global mpl */\nwindow.mpl = {};\n\nmpl.get_websocket_type = function () {\n if (typeof WebSocket !== 'undefined') {\n return WebSocket;\n } else if (typeof MozWebSocket !== 'undefined') {\n return MozWebSocket;\n } else {\n alert(\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\nmpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n this.id = figure_id;\n\n this.ws = websocket;\n\n this.supports_binary = this.ws.binaryType !== undefined;\n\n if (!this.supports_binary) {\n var warnings = document.getElementById('mpl-warnings');\n if (warnings) {\n warnings.style.display = 'block';\n warnings.textContent =\n 'This browser does not support binary websocket messages. ' +\n 'Performance may be slow.';\n }\n }\n\n this.imageObj = new Image();\n\n this.context = undefined;\n this.message = undefined;\n this.canvas = undefined;\n this.rubberband_canvas = undefined;\n this.rubberband_context = undefined;\n this.format_dropdown = undefined;\n\n this.image_mode = 'full';\n\n this.root = document.createElement('div');\n this.root.setAttribute('style', 'display: inline-block');\n this._root_extra_style(this.root);\n\n parent_element.appendChild(this.root);\n\n this._init_header(this);\n this._init_canvas(this);\n this._init_toolbar(this);\n\n var fig = this;\n\n this.waiting = false;\n\n this.ws.onopen = function () {\n fig.send_message('supports_binary', { value: fig.supports_binary });\n fig.send_message('send_image_mode', {});\n if (fig.ratio !== 1) {\n fig.send_message('set_device_pixel_ratio', {\n device_pixel_ratio: fig.ratio,\n });\n }\n fig.send_message('refresh', {});\n };\n\n this.imageObj.onload = function () {\n if (fig.image_mode === 'full') {\n // Full images could contain transparency (where diff images\n // almost always do), so we need to clear the canvas so that\n // there is no ghosting.\n fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n }\n fig.context.drawImage(fig.imageObj, 0, 0);\n };\n\n this.imageObj.onunload = function () {\n fig.ws.close();\n };\n\n this.ws.onmessage = this._make_on_message_function(this);\n\n this.ondownload = ondownload;\n};\n\nmpl.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\nmpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n\nmpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n\nmpl.figure.prototype._init_canvas = function () {\n var fig = this;\n\n var canvas_div = (this.canvas_div = document.createElement('div'));\n canvas_div.setAttribute('tabindex', '0');\n canvas_div.setAttribute(\n 'style',\n 'border: 1px solid #ddd;' +\n 'box-sizing: content-box;' +\n 'clear: both;' +\n 'min-height: 1px;' +\n 'min-width: 1px;' +\n 'outline: 0;' +\n 'overflow: hidden;' +\n 'position: relative;' +\n 'resize: both;' +\n 'z-index: 2;'\n );\n\n function on_keyboard_event_closure(name) {\n return function (event) {\n return fig.key_event(event, name);\n };\n }\n\n canvas_div.addEventListener(\n 'keydown',\n on_keyboard_event_closure('key_press')\n );\n canvas_div.addEventListener(\n 'keyup',\n on_keyboard_event_closure('key_release')\n );\n\n this._canvas_extra_style(canvas_div);\n this.root.appendChild(canvas_div);\n\n var canvas = (this.canvas = document.createElement('canvas'));\n canvas.classList.add('mpl-canvas');\n canvas.setAttribute(\n 'style',\n 'box-sizing: content-box;' +\n 'pointer-events: none;' +\n 'position: relative;' +\n 'z-index: 0;'\n );\n\n this.context = canvas.getContext('2d');\n\n var backingStore =\n this.context.backingStorePixelRatio ||\n this.context.webkitBackingStorePixelRatio ||\n this.context.mozBackingStorePixelRatio ||\n this.context.msBackingStorePixelRatio ||\n this.context.oBackingStorePixelRatio ||\n this.context.backingStorePixelRatio ||\n 1;\n\n this.ratio = (window.devicePixelRatio || 1) / backingStore;\n\n var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n 'canvas'\n ));\n rubberband_canvas.setAttribute(\n 'style',\n 'box-sizing: content-box;' +\n 'left: 0;' +\n 'pointer-events: none;' +\n 'position: absolute;' +\n 'top: 0;' +\n 'z-index: 1;'\n );\n\n // Apply a ponyfill if ResizeObserver is not implemented by browser.\n if (this.ResizeObserver === undefined) {\n if (window.ResizeObserver !== undefined) {\n this.ResizeObserver = window.ResizeObserver;\n } else {\n var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n this.ResizeObserver = obs.ResizeObserver;\n }\n }\n\n this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n var nentries = entries.length;\n for (var i = 0; i < nentries; i++) {\n var entry = entries[i];\n var width, height;\n if (entry.contentBoxSize) {\n if (entry.contentBoxSize instanceof Array) {\n // Chrome 84 implements new version of spec.\n width = entry.contentBoxSize[0].inlineSize;\n height = entry.contentBoxSize[0].blockSize;\n } else {\n // Firefox implements old version of spec.\n width = entry.contentBoxSize.inlineSize;\n height = entry.contentBoxSize.blockSize;\n }\n } else {\n // Chrome <84 implements even older version of spec.\n width = entry.contentRect.width;\n height = entry.contentRect.height;\n }\n\n // Keep the size of the canvas and rubber band canvas in sync with\n // the canvas container.\n if (entry.devicePixelContentBoxSize) {\n // Chrome 84 implements new version of spec.\n canvas.setAttribute(\n 'width',\n entry.devicePixelContentBoxSize[0].inlineSize\n );\n canvas.setAttribute(\n 'height',\n entry.devicePixelContentBoxSize[0].blockSize\n );\n } else {\n canvas.setAttribute('width', width * fig.ratio);\n canvas.setAttribute('height', height * fig.ratio);\n }\n /* This rescales the canvas back to display pixels, so that it\n * appears correct on HiDPI screens. */\n canvas.style.width = width + 'px';\n canvas.style.height = height + 'px';\n\n rubberband_canvas.setAttribute('width', width);\n rubberband_canvas.setAttribute('height', height);\n\n // And update the size in Python. We ignore the initial 0/0 size\n // that occurs as the element is placed into the DOM, which should\n // otherwise not happen due to the minimum size styling.\n if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n fig.request_resize(width, height);\n }\n }\n });\n this.resizeObserverInstance.observe(canvas_div);\n\n function on_mouse_event_closure(name) {\n /* User Agent sniffing is bad, but WebKit is busted:\n * https://bugs.webkit.org/show_bug.cgi?id=144526\n * https://bugs.webkit.org/show_bug.cgi?id=181818\n * The worst that happens here is that they get an extra browser\n * selection when dragging, if this check fails to catch them.\n */\n var UA = navigator.userAgent;\n var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n if(isWebKit) {\n return function (event) {\n /* This prevents the web browser from automatically changing to\n * the text insertion cursor when the button is pressed. We\n * want to control all of the cursor setting manually through\n * the 'cursor' event from matplotlib */\n event.preventDefault()\n return fig.mouse_event(event, name);\n };\n } else {\n return function (event) {\n return fig.mouse_event(event, name);\n };\n }\n }\n\n canvas_div.addEventListener(\n 'mousedown',\n on_mouse_event_closure('button_press')\n );\n canvas_div.addEventListener(\n 'mouseup',\n on_mouse_event_closure('button_release')\n );\n canvas_div.addEventListener(\n 'dblclick',\n on_mouse_event_closure('dblclick')\n );\n // Throttle sequential mouse events to 1 every 20ms.\n canvas_div.addEventListener(\n 'mousemove',\n on_mouse_event_closure('motion_notify')\n );\n\n canvas_div.addEventListener(\n 'mouseenter',\n on_mouse_event_closure('figure_enter')\n );\n canvas_div.addEventListener(\n 'mouseleave',\n on_mouse_event_closure('figure_leave')\n );\n\n canvas_div.addEventListener('wheel', function (event) {\n if (event.deltaY < 0) {\n event.step = 1;\n } else {\n event.step = -1;\n }\n on_mouse_event_closure('scroll')(event);\n });\n\n canvas_div.appendChild(canvas);\n canvas_div.appendChild(rubberband_canvas);\n\n this.rubberband_context = rubberband_canvas.getContext('2d');\n this.rubberband_context.strokeStyle = '#000000';\n\n this._resize_canvas = function (width, height, forward) {\n if (forward) {\n canvas_div.style.width = width + 'px';\n canvas_div.style.height = height + 'px';\n }\n };\n\n // Disable right mouse context menu.\n canvas_div.addEventListener('contextmenu', function (_e) {\n event.preventDefault();\n return false;\n });\n\n function set_focus() {\n canvas.focus();\n canvas_div.focus();\n }\n\n window.setTimeout(set_focus, 100);\n};\n\nmpl.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\nmpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n // which will in turn request a refresh of the image.\n this.send_message('resize', { width: x_pixels, height: y_pixels });\n};\n\nmpl.figure.prototype.send_message = function (type, properties) {\n properties['type'] = type;\n properties['figure_id'] = this.id;\n this.ws.send(JSON.stringify(properties));\n};\n\nmpl.figure.prototype.send_draw_message = function () {\n if (!this.waiting) {\n this.waiting = true;\n this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n }\n};\n\nmpl.figure.prototype.handle_save = function (fig, _msg) {\n var format_dropdown = fig.format_dropdown;\n var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n fig.ondownload(fig, format);\n};\n\nmpl.figure.prototype.handle_resize = function (fig, msg) {\n var size = msg['size'];\n if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n fig._resize_canvas(size[0], size[1], msg['forward']);\n fig.send_message('refresh', {});\n }\n};\n\nmpl.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\nmpl.figure.prototype.handle_figure_label = function (fig, msg) {\n // Updates the figure title.\n fig.header.textContent = msg['label'];\n};\n\nmpl.figure.prototype.handle_cursor = function (fig, msg) {\n fig.canvas_div.style.cursor = msg['cursor'];\n};\n\nmpl.figure.prototype.handle_message = function (fig, msg) {\n fig.message.textContent = msg['message'];\n};\n\nmpl.figure.prototype.handle_draw = function (fig, _msg) {\n // Request the server to send over a new figure.\n fig.send_draw_message();\n};\n\nmpl.figure.prototype.handle_image_mode = function (fig, msg) {\n fig.image_mode = msg['mode'];\n};\n\nmpl.figure.prototype.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\nmpl.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\nmpl.figure.prototype.updated_canvas_event = function () {\n // Called whenever the canvas gets updated.\n this.send_message('ack', {});\n};\n\n// A function to construct a web socket function for onmessage handling.\n// Called in the figure constructor.\nmpl.figure.prototype._make_on_message_function = function (fig) {\n return function socket_on_message(evt) {\n if (evt.data instanceof Blob) {\n var img = evt.data;\n if (img.type !== 'image/png') {\n /* FIXME: We get \"Resource interpreted as Image but\n * transferred with MIME type text/plain:\" errors on\n * Chrome. But how to set the MIME type? It doesn't seem\n * to be part of the websocket stream */\n img.type = 'image/png';\n }\n\n /* Free the memory for the previous frames */\n if (fig.imageObj.src) {\n (window.URL || window.webkitURL).revokeObjectURL(\n fig.imageObj.src\n );\n }\n\n fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n img\n );\n fig.updated_canvas_event();\n fig.waiting = false;\n return;\n } else if (\n typeof evt.data === 'string' &&\n evt.data.slice(0, 21) === 'data:image/png;base64'\n ) {\n fig.imageObj.src = evt.data;\n fig.updated_canvas_event();\n fig.waiting = false;\n return;\n }\n\n var msg = JSON.parse(evt.data);\n var msg_type = msg['type'];\n\n // Call the \"handle_{type}\" callback, which takes\n // the figure and JSON message as its only arguments.\n try {\n var callback = fig['handle_' + msg_type];\n } catch (e) {\n console.log(\n \"No handler for the '\" + msg_type + \"' message type: \",\n msg\n );\n return;\n }\n\n if (callback) {\n try {\n // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n callback(fig, msg);\n } catch (e) {\n console.log(\n \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n e,\n e.stack,\n msg\n );\n }\n }\n };\n};\n\nfunction getModifiers(event) {\n var mods = [];\n if (event.ctrlKey) {\n mods.push('ctrl');\n }\n if (event.altKey) {\n mods.push('alt');\n }\n if (event.shiftKey) {\n mods.push('shift');\n }\n if (event.metaKey) {\n mods.push('meta');\n }\n return mods;\n}\n\n/*\n * return a copy of an object with only non-object keys\n * we need this to avoid circular references\n * https://stackoverflow.com/a/24161582/3208463\n */\nfunction 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\nmpl.figure.prototype.mouse_event = function (event, name) {\n if (name === 'button_press') {\n this.canvas.focus();\n this.canvas_div.focus();\n }\n\n // from https://stackoverflow.com/q/1114465\n var boundingRect = this.canvas.getBoundingClientRect();\n var x = (event.clientX - boundingRect.left) * this.ratio;\n var y = (event.clientY - boundingRect.top) * this.ratio;\n\n this.send_message(name, {\n x: x,\n y: y,\n button: event.button,\n step: event.step,\n modifiers: getModifiers(event),\n guiEvent: simpleKeys(event),\n });\n\n return false;\n};\n\nmpl.figure.prototype._key_event_extra = function (_event, _name) {\n // Handle any extra behaviour associated with a key event\n};\n\nmpl.figure.prototype.key_event = function (event, name) {\n // Prevent repeat events\n if (name === 'key_press') {\n if (event.key === this._key) {\n return;\n } else {\n this._key = event.key;\n }\n }\n if (name === 'key_release') {\n this._key = null;\n }\n\n var value = '';\n if (event.ctrlKey && event.key !== 'Control') {\n value += 'ctrl+';\n }\n else if (event.altKey && event.key !== 'Alt') {\n value += 'alt+';\n }\n else if (event.shiftKey && event.key !== 'Shift') {\n value += 'shift+';\n }\n\n value += 'k' + event.key;\n\n this._key_event_extra(event, name);\n\n this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n return false;\n};\n\nmpl.figure.prototype.toolbar_button_onclick = function (name) {\n if (name === 'download') {\n this.handle_save(this, null);\n } else {\n this.send_message('toolbar_button', { name: name });\n }\n};\n\nmpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n this.message.textContent = tooltip;\n};\n\n///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n// prettier-ignore\nvar _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\nmpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n\nmpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n\nmpl.default_extension = \"png\";/* global mpl */\n\nvar comm_websocket_adapter = function (comm) {\n // Create a \"websocket\"-like object which calls the given IPython comm\n // object with the appropriate methods. Currently this is a non binary\n // socket, so there is still some room for performance tuning.\n var ws = {};\n\n ws.binaryType = comm.kernel.ws.binaryType;\n ws.readyState = comm.kernel.ws.readyState;\n function updateReadyState(_event) {\n if (comm.kernel.ws) {\n ws.readyState = comm.kernel.ws.readyState;\n } else {\n ws.readyState = 3; // Closed state.\n }\n }\n comm.kernel.ws.addEventListener('open', updateReadyState);\n comm.kernel.ws.addEventListener('close', updateReadyState);\n comm.kernel.ws.addEventListener('error', updateReadyState);\n\n ws.close = function () {\n comm.close();\n };\n ws.send = function (m) {\n //console.log('sending', m);\n comm.send(m);\n };\n // Register the callback with on_msg.\n comm.on_msg(function (msg) {\n //console.log('receiving', msg['content']['data'], msg);\n var data = msg['content']['data'];\n if (data['blob'] !== undefined) {\n data = {\n data: new Blob(msg['buffers'], { type: data['blob'] }),\n };\n }\n // Pass the mpl event to the overridden (by mpl) onmessage function.\n ws.onmessage(data);\n });\n return ws;\n};\n\nmpl.mpl_figure_comm = function (comm, msg) {\n // This is the function which gets called when the mpl process\n // starts-up an IPython Comm through the \"matplotlib\" channel.\n\n var id = msg.content.data.id;\n // Get hold of the div created by the display call when the Comm\n // socket was opened in Python.\n var element = document.getElementById(id);\n var ws_proxy = comm_websocket_adapter(comm);\n\n function ondownload(figure, _format) {\n window.open(figure.canvas.toDataURL());\n }\n\n var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n\n // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n // web socket which is closed, not our websocket->open comm proxy.\n ws_proxy.onopen();\n\n fig.parent_element = element;\n fig.cell_info = mpl.find_output_cell(\"\");\n if (!fig.cell_info) {\n console.error('Failed to find cell for figure', id, fig);\n return;\n }\n fig.cell_info[0].output_area.element.on(\n 'cleared',\n { fig: fig },\n fig._remove_fig_handler\n );\n};\n\nmpl.figure.prototype.handle_close = function (fig, msg) {\n var width = fig.canvas.width / fig.ratio;\n fig.cell_info[0].output_area.element.off(\n 'cleared',\n fig._remove_fig_handler\n );\n fig.resizeObserverInstance.unobserve(fig.canvas_div);\n\n // Update the output cell to use the data from the current canvas.\n fig.push_to_output();\n var dataURL = fig.canvas.toDataURL();\n // Re-enable the keyboard manager in IPython - without this line, in FF,\n // the notebook keyboard shortcuts fail.\n IPython.keyboard_manager.enable();\n fig.parent_element.innerHTML =\n '
';\n fig.close_ws(fig, msg);\n};\n\nmpl.figure.prototype.close_ws = function (fig, msg) {\n fig.send_message('closing', msg);\n // fig.ws.close()\n};\n\nmpl.figure.prototype.push_to_output = function (_remove_interactive) {\n // Turn the data on the canvas into data in the output cell.\n var width = this.canvas.width / this.ratio;\n var dataURL = this.canvas.toDataURL();\n this.cell_info[1]['text/html'] =\n '
';\n};\n\nmpl.figure.prototype.updated_canvas_event = function () {\n // Tell IPython that the notebook contents must change.\n IPython.notebook.set_dirty(true);\n this.send_message('ack', {});\n var fig = this;\n // Wait a second, then push the new image to the DOM so\n // that it is saved nicely (might be nice to debounce this).\n setTimeout(function () {\n fig.push_to_output();\n }, 1000);\n};\n\nmpl.figure.prototype._init_toolbar = function () {\n var fig = this;\n\n var toolbar = document.createElement('div');\n toolbar.classList = 'btn-toolbar';\n this.root.appendChild(toolbar);\n\n function on_click_closure(name) {\n return function (_event) {\n return fig.toolbar_button_onclick(name);\n };\n }\n\n function on_mouseover_closure(tooltip) {\n return function (event) {\n if (!event.currentTarget.disabled) {\n return fig.toolbar_button_onmouseover(tooltip);\n }\n };\n }\n\n fig.buttons = {};\n var buttonGroup = document.createElement('div');\n buttonGroup.classList = 'btn-group';\n var button;\n for (var toolbar_ind in mpl.toolbar_items) {\n var name = mpl.toolbar_items[toolbar_ind][0];\n var tooltip = mpl.toolbar_items[toolbar_ind][1];\n var image = mpl.toolbar_items[toolbar_ind][2];\n var method_name = mpl.toolbar_items[toolbar_ind][3];\n\n if (!name) {\n /* Instead of a spacer, we start a new button group. */\n if (buttonGroup.hasChildNodes()) {\n toolbar.appendChild(buttonGroup);\n }\n buttonGroup = document.createElement('div');\n buttonGroup.classList = 'btn-group';\n continue;\n }\n\n button = fig.buttons[name] = document.createElement('button');\n button.classList = 'btn btn-default';\n button.href = '#';\n button.title = name;\n button.innerHTML = '';\n button.addEventListener('click', on_click_closure(method_name));\n button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n buttonGroup.appendChild(button);\n }\n\n if (buttonGroup.hasChildNodes()) {\n toolbar.appendChild(buttonGroup);\n }\n\n // Add the status bar.\n var status_bar = document.createElement('span');\n status_bar.classList = 'mpl-message pull-right';\n toolbar.appendChild(status_bar);\n this.message = status_bar;\n\n // Add the close button to the window.\n var buttongrp = document.createElement('div');\n buttongrp.classList = 'btn-group inline pull-right';\n button = document.createElement('button');\n button.classList = 'btn btn-mini btn-primary';\n button.href = '#';\n button.title = 'Stop Interaction';\n button.innerHTML = '';\n button.addEventListener('click', function (_evt) {\n fig.handle_close(fig, {});\n });\n button.addEventListener(\n 'mouseover',\n on_mouseover_closure('Stop Interaction')\n );\n buttongrp.appendChild(button);\n var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n titlebar.insertBefore(buttongrp, titlebar.firstChild);\n};\n\nmpl.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\nmpl.figure.prototype._root_extra_style = function (el) {\n el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n};\n\nmpl.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\nmpl.figure.prototype._key_event_extra = function (event, _name) {\n // Check for shift+enter\n if (event.shiftKey && event.which === 13) {\n this.canvas_div.blur();\n // select the cell after this one\n var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n IPython.notebook.select(index + 1);\n }\n};\n\nmpl.figure.prototype.handle_save = function (fig, _msg) {\n fig.ondownload(fig, null);\n};\n\nmpl.find_output_cell = function (html_output) {\n // Return the cell and output element which can be found *uniquely* in the notebook.\n // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n // IPython event is triggered only after the cells have been serialised, which for\n // our purposes (turning an active figure into a static one), is too late.\n var cells = IPython.notebook.get_cells();\n var ncells = cells.length;\n for (var i = 0; i < ncells; i++) {\n var cell = cells[i];\n if (cell.cell_type === 'code') {\n for (var j = 0; j < cell.output_area.outputs.length; j++) {\n var data = cell.output_area.outputs[j];\n if (data.data) {\n // IPython >= 3 moved mimebundle to data attribute of output\n data = data.data;\n }\n if (data['text/html'] === html_output) {\n return [cell, data, j];\n }\n }\n }\n }\n};\n\n// Register the function which deals with the matplotlib target/channel.\n// The kernel may be null if the page has been refreshed.\nif (IPython.notebook.kernel !== null) {\n IPython.notebook.kernel.comm_manager.register_target(\n 'matplotlib',\n mpl.mpl_figure_comm\n );\n}\n",
"text/plain": [
""
]
@@ -1034,7 +86,7 @@
{
"data": {
"text/html": [
- "
"
+ ""
],
"text/plain": [
""
@@ -1042,20 +94,11 @@
},
"metadata": {},
"output_type": "display_data"
- },
- {
- "data": {
- "text/plain": [
- "[]"
- ]
- },
- "execution_count": 4,
- "metadata": {},
- "output_type": "execute_result"
}
],
"source": [
- "plt.plot(data)"
+ "plt.plot(data)\n",
+ "plt.show()"
]
},
{
@@ -1136,7 +179,7 @@
},
{
"data": {
- "image/png": "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\n",
+ "image/png": "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",
"text/plain": [
""
]
@@ -1184,7 +227,7 @@
},
{
"data": {
- "image/png": "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\n",
+ "image/png": "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",
"text/plain": [
""
]
@@ -1259,7 +302,7 @@
],
"metadata": {
"kernelspec": {
- "display_name": "Python 3 (ipykernel)",
+ "display_name": "Python 3.9.19 ('matplotlib')",
"language": "python",
"name": "python3"
},
@@ -1273,7 +316,12 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
- "version": "3.8.12"
+ "version": "3.9.19"
+ },
+ "vscode": {
+ "interpreter": {
+ "hash": "1c3a946ddf3ee7cda41fa133e6366d1351543b92c771f65a565514f942d3e40d"
+ }
}
},
"nbformat": 4,
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000..00ba4b4
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1,42 @@
+appnope==0.1.4
+asttokens==2.4.1
+comm==0.2.2
+contourpy==1.2.0
+cycler==0.12.1
+debugpy==1.8.1
+decorator==5.1.1
+exceptiongroup==1.2.0
+executing==2.0.1
+fonttools==4.50.0
+importlib_metadata==7.1.0
+importlib_resources==6.4.0
+ipykernel==6.29.4
+ipython==8.18.1
+jedi==0.19.1
+jupyter_client==8.6.1
+jupyter_core==5.7.2
+kiwisolver==1.4.5
+matplotlib==3.8.3
+matplotlib-inline==0.1.6
+nest-asyncio==1.6.0
+numpy==1.26.4
+packaging==24.0
+parso==0.8.3
+pexpect==4.9.0
+pillow==10.2.0
+platformdirs==4.2.0
+prompt-toolkit==3.0.43
+psutil==5.9.8
+ptyprocess==0.7.0
+pure-eval==0.2.2
+Pygments==2.17.2
+pyparsing==3.1.2
+python-dateutil==2.9.0.post0
+pyzmq==25.1.2
+six==1.16.0
+stack-data==0.6.3
+tornado==6.4
+traitlets==5.14.2
+typing_extensions==4.10.0
+wcwidth==0.2.13
+zipp==3.18.1